问题描述
想实现a,b,c,d四个线程并行运行,要求d线程依赖于abc三个线程,abc三个线程执行完才能执行d线程,b线程依赖于c线程,c线程执行完才能执行b线程,以下是我写的代码,a、c线程执行完毕后就挂起了,不知道问题在哪儿,求指教package test.com.cn;public class ThreadTest{public static void main(String[] args) {Signal s = new Signal(); Runnable at = new MyThreadABC(s,"A");Runnable bt = new MyThreadABC(s,"B");Runnable ct = new MyThreadABC(s,"C");Runnable dt = new MyThreadD(s,"D");new Thread(at).start();new Thread(bt).start();new Thread(ct).start();new Thread(dt).start(); }}class Signal{//private boolean abcend;private Boolean bend = false;private Boolean cend = false;private Boolean aend = false;public boolean isAend() {return aend;}public void setAend(boolean aend) {this.aend = aend;}public boolean isBend() {return bend;}public void setBend(boolean bend) {this.bend = bend;}public synchronized boolean isCend() throws InterruptedException {synchronized (cend) {while(!cend){wait();}}notifyAll();return cend;}public synchronized void setCend(Boolean cend) {synchronized (cend) {this.cend = cend;}}//public boolean isDend() {//return dend;//}//public void setDend(boolean dend) {//this.dend = dend;//}//public synchronized boolean isAbcEnd() throws InterruptedException{synchronized(this){while(!(aend&&bend&&cend)){wait();}}notifyAll();return Boolean.valueOf(aend&&bend&&cend);} }class MyThreadABC implements Runnable{private Signal signal;private String tid;public String getTid() {return tid;}public void setTid(String tid) {this.tid = tid;}public Signal getSignal() {return signal;}public MyThreadABC(Signal signal,String tid) {this.signal = signal;this.tid = tid;}public void setSignal(Signal signal) {this.signal = signal;}public void run() {if(tid=="A")signal.setAend(true);try {if(tid=="B"&&signal.isCend())signal.setBend(true);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}if(tid=="C"){signal.setCend(true);}System.out.println("我是进程"+tid+",执行完毕");}}class MyThreadD implements Runnable{private Signal signal;private String tid;public String getTid() {return tid;}public void setTid(String tid) {this.tid = tid;}public Signal getSignal() {return signal;}public MyThreadD(Signal signal,String tid) {this.signal = signal;this.tid = tid;}public void setSignal(Signal signal) {this.signal = signal;} public void run() {try {if(signal.isAbcEnd()){ System.out.println("我是进程"+tid+",执行完毕");}} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}执行结果:我是进程A,执行完毕 我是进程C,执行完毕
解决方案
package test.thread.concurrent;import java.util.Random;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.TimeUnit;/** * @author yu <br/> * Created date: 2013-3-7 <br/> */public class CyclicBarrierTest { Thread a = new Thread(new Runnable() { @Override public void run() { try { System.out.println("Thread A started..."); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println("Thread A starts waiting..."); waitAbc.await(); // waiting } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }); Thread b = new Thread(new Runnable() { @Override public void run() { try { System.out.println("Thread B started..."); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println("Thread B is waiting..."); waitAbc.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }); Thread c = new Thread(new Runnable() { @Override public void run() { try { System.out.println("Thread C started..."); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println("Thread C starts waiting..."); waitC.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }); Thread d = new Thread(new Runnable() { @Override public void run() { try { System.out.println("Thread D started..."); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println("Thread D ends.."); } catch (InterruptedException e) { e.printStackTrace(); } } }); // waiting c execute and execute b CyclicBarrier waitC = new CyclicBarrier(1, new Runnable() { @Override public void run() { System.out.println("Thread C ends, starting B..."); b.start(); } }); // waiting a,b(,c) execute d CyclicBarrier waitAbc = new CyclicBarrier(2, new Runnable() { @Override public void run() { System.out.println("Thread A, B, C ends, starting D..."); d.start(); } }); public static void main(String[] args) { CyclicBarrierTest test = new CyclicBarrierTest(); test.a.start(); test.c.start(); }}某一次的运行结果引用Thread A started...Thread C started...Thread A starts waiting...Thread C starts waiting...Thread C ends, starting B...Thread B started...Thread B is waiting...Thread A, B, C ends, starting D...Thread D started...Thread D ends..
解决方案二:
比如你的B线程执行到代码39行,然后停在那里等待了。但是没有其他线程能唤醒它,检查下代码吧。比如在setCend里面唤醒一下其他线程。自己再调调。加油!
解决方案三:
对于你这个例子,个人更偏好CountDownLatch, 反正两个例子都有了,你自己看package test.thread.concurrent;import java.util.Random;import java.util.concurrent.CountDownLatch;import java.util.concurrent.TimeUnit;/** * @author yale.yu <br/> * Created date: 2013-3-7 <br/> */public class CountDownLatchTest { CountDownLatch lockC = new CountDownLatch(1); CountDownLatch lockABC = new CountDownLatch(3); Thread a = new Thread(new Runnable() { @Override public void run() { try { System.out.println("Thread A executing..."); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println("Thread A starts executed..."); lockABC.countDown(); // change counter } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread b = new Thread(new Runnable() { @Override public void run() { try { lockC.await(); //waiting c System.out.println("Thread B executing..."); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println("Thread B is executed..."); lockABC.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread c = new Thread(new Runnable() { @Override public void run() { try { System.out.println("Thread C executing..."); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println("Thread C starts executed..."); lockC.countDown(); lockABC.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread d = new Thread(new Runnable() { @Override public void run() { try { lockABC.await(); //waiting a,b,c System.out.println("Thread D executing..."); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println("Thread D ends.."); } catch (InterruptedException e) { e.printStackTrace(); } } }); public static void main(String[] args) { CountDownLatchTest test = new CountDownLatchTest(); test.a.start(); test.b.start(); test.c.start(); test.d.start(); }}引用Thread A executing...Thread C executing...Thread A starts executed...Thread C starts executed...Thread B executing...Thread B is executed...Thread D executing...Thread D ends..
解决方案四:
代码没时间给你写,你去看看:java.util.concurrent.CyclicBarrier