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++的位置不同,却产生了不一样的结果?
结果不同并不是i的位置引起的。
因为i被并发修改了,即便是相同的代码执行几遍也可能不一样
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次啊
啥意思??你想看到什么。你想看到i被并发修改吗?本身MyThread 和MyThread2就是两个实例化。他俩不会并发访问一个i的。只有t1 t2 t3有可能并发访问同一个i但是你的循环太短 join的时间太长。这样的话等t2 t3获取cpu时间的时候,i已经是10了所以一直是t1在跑。你可以把t1 t2 t3 setName 就知道了
多线程的东西你想看到你想看的东西 最好把循环次数调高点 不然时间太短 有时候看不到问题的
你的i++不是一个原子操作,实际上在++时候会有3步,你需要换成AtomicInteger来完成你的逻辑
你的i++不是一个原子操作,实际上在++时候会有3步,你需要换成AtomicInteger来完成你的逻辑