线程按顺序执行

线程按顺序执行
这是一个要求线程按顺序执行的代码importjava.util.*;publicclassseqTest{publicstaticvoidmain(String[]args){myRunnable r1newmyRunnable(1);Threadt1newThread(r1);myRunnable r2newmyRunnable(2);Threadt2newThread(r2);myRunnable r3newmyRunnable(3);Threadt3newThread(r3);t1.start();t2.start();t3.start();}}classmyRunnableimplementsRunnable{privatestaticObjectlocknewObject();privatestaticintturn1;privateintID;publicvoidmyRunnable(){}publicmyRunnable(intID){this.IDID;}publicvoidrun(){for(inti0;i3;i){//这个for循环是为了让每个线程能执行三次synchronized(lock){try{while(turn!ID){lock.wait();}System.out.println(ThreadID执行);if(ID1)turn2;elseif(ID2)turn3;elseif(ID3)turn1;lock.notifyAll();}catch(Exceptione){e.printStackTrace();}}}}}写这段代码中发现自己对线程理解出现的三个问题问题1线程自动调用的方法当线程调用start()后JVM 会为该线程开辟独立的栈空间并自动调用其run()方法。我们无需也不能直接调用run()只能由 JVM 在线程启动后自动触发。问题2线程wait()后是怎么运行的当线程执行到lock.wait()后它会立即进入等待集并释放锁wait()之后的代码暂停执行。当该线程后续被其他线程唤醒并重新获得锁时会从wait()之后的第一条语句继续执行而不是重新进入同步块的开头。其执行流程可用以下代码块抽象展示synchronized(lock){while(条件不满足){// 线程执行到这里lock.wait();// 被唤醒后从这里继续执行}// 执行任务}问题3为什么三个线程看似在同一个run()方法中交替执行首先要明确每个线程执行的是各自独立的run()方法。之所以看起来像是在同一个run()中交替执行是因为三个线程共用同一把锁lock并且通过wait()/notifyAll()机制实现了严格的顺序调度——任意时刻只有拿到锁的线程能够执行同步块内的代码其他线程要么被阻塞在入口处要么处于等待集中。下面的时序表可以直观地展示三个线程与锁状态的交替过程时间线程1线程2线程3lock 状态t1执行到 synchronized执行到 synchronized执行到 synchronized空闲t2拿到锁进入等待blocked等待blocked被线程1持有t3执行代码等待等待被线程1持有t4lock.wait()等待等待释放空闲t5进入等待集竞争锁竞争锁被线程2拿到t6在等待集拿到锁进入等待被线程2持有t7在等待集执行代码等待被线程2持有t8在等待集lock.notifyAll()等待被线程2持有t9被唤醒移到入口集退出同步块还在等待释放空闲t10竞争锁已退出竞争锁被线程3拿到t11等待线程2结束拿到锁进入被线程3持有t12等待执行代码被线程3持有t13等待lock.notifyAll()被线程3持有t14竞争锁退出同步块释放空闲t15拿到锁进入线程3结束被线程1持有t16从 wait() 后继续执行-被线程1持有t17执行剩余代码-被线程1持有t18退出同步块-释放空闲

最新新闻

日新闻

周新闻

月新闻