首页 新闻 搜索 专区 学院

java多线程的一个疑问

0
悬赏园豆:20 [待解决问题]

package com.me.thread_sleep;

class MyThread implements Runnable {
    int i = 1;
    
    @Override
    public void run() {
        for (; i <= 10;) {
            System.out.println(Thread.currentThread().getName()+":"+i);
            i++;
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                // TODO Auto-generated catch block
//                e.printStackTrace();
//            }
        }
        
//        while(i <= 10) {
//            System.out.println(Thread.currentThread().getName()+":"+i++);
//        }
    }
}

class MyThread2 implements Runnable {
    int i = 1;
    
    @Override
    public void run() {
        for (; i <= 10;) {
            System.out.println(Thread.currentThread().getName()+":"+i++);
//            
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                // TODO Auto-generated catch block
//                e.printStackTrace();
//            }
        }
        
//        while(i <= 10) {
//            System.out.println(Thread.currentThread().getName()+":"+i++);
//        }
    }
}

public class SleepDemo {

    public static void main(String[] args) {
//        //extends Thread
//        new MyThread().start();
//        new MyThread().start();
//        new MyThread().start();
        System.out.println("for i++");
        
        MyThread myThread = new MyThread();
        Thread t1 = new Thread(myThread);
        Thread t2 = new Thread(myThread);
        Thread t3 = new Thread(myThread);
        
        t1.start();
        t2.start();
        t3.start();
        
        try {
            t1.join(1000);
            t2.join(1000);
            t3.join(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        System.out.println("******************");
        System.out.println("sop i++");
        
        MyThread2 myThread2 = new MyThread2();
        Thread t4 = new Thread(myThread2);
        Thread t5 = new Thread(myThread2);
        Thread t6 = new Thread(myThread2);
        
        t4.start();
        t5.start();
        t6.start();
    }

}

 

为什么MyThread 和MyThread2仅仅是i++的位置不同,却产生了不一样的结果?

pxy的主页 pxy | 初学一级 | 园豆:182
提问于:2017-11-22 23:47
< >
分享
所有回答(4)
0

结果不同并不是i的位置引起的。

因为i被并发修改了,即便是相同的代码执行几遍也可能不一样

liqipeng | 园豆:1160 (小虾三级) | 2017-11-23 00:24

for i++
Thread-1:1
Thread-0:1
Thread-0:3
Thread-0:4
Thread-0:5
Thread-0:6
Thread-0:7
Thread-0:8
Thread-2:1
Thread-0:9
Thread-1:2
Thread-2:10
******************
sop i++
Thread-3:1
Thread-4:2
Thread-4:5
Thread-4:6
Thread-4:7
Thread-4:8
Thread-4:9
Thread-5:3
Thread-4:10
Thread-3:4

 

-------------------------------------------

我这边执行的效果,不存在1次,3次啊

支持(0) 反对(0) kirck007 | 园豆:223 (菜鸟二级) | 2017-11-23 09:08
0

啥意思??你想看到什么。你想看到i被并发修改吗?本身MyThread 和MyThread2就是两个实例化。他俩不会并发访问一个i的。只有t1 t2 t3有可能并发访问同一个i但是你的循环太短 join的时间太长。这样的话等t2  t3获取cpu时间的时候,i已经是10了所以一直是t1在跑。你可以把t1  t2 t3  setName 就知道了

初学者max | 园豆:257 (菜鸟二级) | 2017-11-23 09:12

多线程的东西你想看到你想看的东西 最好把循环次数调高点 不然时间太短 有时候看不到问题的

支持(0) 反对(0) 初学者max | 园豆:257 (菜鸟二级) | 2017-11-23 09:20
0

你的i++不是一个原子操作,实际上在++时候会有3步,你需要换成AtomicInteger来完成你的逻辑

Daniel Cai | 园豆:10374 (专家六级) | 2017-11-23 09:59
0

你的i++不是一个原子操作,实际上在++时候会有3步,你需要换成AtomicInteger来完成你的逻辑

fcyh | 园豆:568 (小虾三级) | 2017-11-24 14:35
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册