关于多线程的问题

想实现a,b,c,d四个线程并行运行,要求d线程依赖于abc三个线程,abc三个线程执行完才能执行d线程,b线程依赖于c线程,c线程执行完才能执行b线程,以下是我写的代码,a、c线程执行完毕后就挂起了,不知道问题在哪儿,求指教
[code="java"]
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 block
        e.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 block
            e.printStackTrace();
        }
    }

}

[/code]

执行结果:我是进程A,执行完毕
我是进程C,执行完毕

[code="java"]
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
  • Created date: 2013-3-7

    */
    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();
    }

}

[/code]

某一次的运行结果
[quote]
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..

[/quote]

代码没时间给你写,你去看看:java.util.concurrent.CyclicBarrier

对于你这个例子,个人更偏好CountDownLatch, 反正两个例子都有了,你自己看

[code="java"]
package test.thread.concurrent;

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**

  • @author yale.yu
  • Created date: 2013-3-7

    */
    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();
    }

}

[/code]

[quote]
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..

[/quote]

比如你的B线程执行到代码39行,然后停在那里等待了。但是没有其他线程能唤醒它,检查下代码吧。比如在setCend里面唤醒一下其他线程。自己再调调。加油!