Java线程同步未按预期工作,输出顺序异常的原因解析
Java线程同步执行顺序偏差问题解析
示例代码
class AB{ synchronized public void print(String name) { for(int i=0;i<5;i++) { System.out.println(name+" "+i); try { Thread.sleep(1000); } catch(InterruptedException e) { e.printStackTrace(); } } } } //extending thread is another way. Usually we use Runnable Interface class NewThread implements Runnable{ String name; AB obj; Thread t; NewThread(String name,AB o){ this.name=name; obj=o; t=new Thread(this,name); t.start(); } public void run() { obj.print(name); } } public class ThreadExample { public static void main(String g[]) { AB t=new AB(); NewThread t1=new NewThread("1",t); System.out.println("A"); NewThread t2=new NewThread("2",t); System.out.println("B"); NewThread t3=new NewThread("3",t); System.out.println("C"); //join is similar to wait for processes. Parent thread(main) waits for children to terminate //note that without synchronization, all three threads execute simultaneously. try { t1.t.join(); t2.t.join(); t3.t.join(); } catch(InterruptedException e) { e.printStackTrace(); } for(int i=0;i<5;i++) { System.out.println("main thread"+" "+i); try { Thread.sleep(1000); } catch(InterruptedException e) { e.printStackTrace(); } } } }
问题描述
预期输出顺序为t1线程输出→A→t2线程输出→B→t3线程输出→C→main线程输出,但实际输出顺序是A→B→C→t1→t3→t2→main,明明给print方法加了synchronized关键字,为什么会出现这种偏差?
原因解析
- 线程启动是异步操作:调用
Thread.start()后,线程不会立刻执行run方法,只是进入就绪状态等待CPU调度。main线程在启动t1后,会直接继续执行System.out.println("A"),不会等待t1的run方法执行完毕。同理,t2、t3启动后,main线程也会立刻打印B、C,不会暂停。 - synchronized的作用边界:
synchronized修饰print方法,仅保证同一个AB实例的print方法不能被多个线程同时执行,也就是t1、t2、t3的print调用会互斥执行,但它管不了main线程的执行流程,也管不了线程的启动顺序和CPU调度优先级。 - join方法的执行时机:代码里的
join()是在打印完A、B、C之后才调用的,所以main线程会先把A、B、C全部打印完成,才开始等待三个子线程结束,最后执行自己的循环输出。
内容的提问来源于stack exchange,提问作者Tejas Hegde
相关产品推荐
相关产品推荐

