关于线程抢占的一些问题

csdn_java__li 2020-02-23 11:19:07

public class MyRunnable implements Runnable{
private int n = 10;
@Override
public void run() {
// TODO Auto-generated method stub
while (n > 0) {
System.out.println(Thread.currentThread().getName()+":"+n--);

}

}
}


public class DemoThread {
public static void main(String[] args) {
MyRunnable mr = new MyRunnable();
Thread t1 = new Thread(mr, "线程1");
Thread t2 = new Thread(mr, "线程2");
t1.start();
t2.start();
}
}

结果:
线程1:10
线程2:10
线程2:8
线程2:7
线程2:6
线程2:5
线程1:9
线程2:4
线程2:2
线程1:3
线程2:1

问题:可以理解在线程抢占的过程中,出现重复,但是程序是按流执行的,为什么9会出现在5后面以及3会出现在2后面?
...全文
205 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
BoRoBoRoMe 2020-02-23
  • 打赏
  • 举报
回复
n--不是原子操作 n--等价于方法 int getN() { int v = n; n--; return v; } 所以刚开始的时候线程1,2都同时拿到了10 之后线程1,拿到了9,之后还没有输出转到线程2 线程2拿到了数字8,7,6,5,并输出 ,之后轮到线程1输出 结果线程1输出9 ... 其他类似,不重复了 关键是线程操作要使用线程安全的操作 或者增加锁 比如将代码修改成这个样子

public class MyRunnable implements Runnable{
    private int n = 10;
    @Override
    public void run() {
        while (true) {
            int v = getN();
            if (v <= 0) {
                break; 
            }
            System.out.println(Thread.currentThread().getName()+":"v);
        }
    }

    private synchronized int getN() {
        int v = n;
        n--;
        return v;
    }
}
宾灬 2020-02-23
  • 打赏
  • 举报
回复
没有覆盖, System.out.println(Thread.currentThread().getName()+":"+n--); 这行代码,当n=9时 刚好是线程1在执行,调用这个System.out.println()方法的时候给的参数就是9,这里的参数传递是值传递,相当于把n=9复制了一份出来,原来的n即使在减小,也不会影响System.out.println()这个方法中传过来的参数n。
csdn_java__li 2020-02-23
  • 打赏
  • 举报
回复
还是没懂,我明白n--是方法
直接说一下我的思路:
根据结果
1.首先线程1抢占输出
2.线程2抢占输出
3.线程1抢占实现方法n--,此时n=9
4.线程2抢占实现方法n--,此时n=8,9被覆盖了
5.线程2继续抢占实现输出8
6.线程2抢占实现方法n--,此时n=7
7.线程2继续抢占实现输出7
...
当线程1抢占输出的时候为什么n=9,9不是被n--方法更改了吗??

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧