在多线程中使用wait()和notify()

时间:2013-10-17 08:28:02

标签: java multithreading concurrency

我正在尝试wait()notify()多线程方法。

我想出了一个小项目,我试图通过多线程来解决这个问题。 我有一辆出租车,将达到等级6,我有一辆乘客将达到Rank6。

出租车将在乘客之前到达等级6,乘客将wait()。 当乘客达到Rank6时,他将notify()

在收到通知后,该出租车将继续循环,并且不会对其他等级。

Taxi.java

package multhithreading.engage.hireForHier;

public class Taxi implements Runnable {

Rank rank = null;

public Taxi(Rank rank) {
    this.rank = rank;
}

public void run() {
    System.out.println(Thread.currentThread().getName() + "  Destined for rank No. " + rank.getRankNo());
    synchronized (rank) {

        for (int i = 1; i < 10; i++) {
            System.out.println("Taxi has reached rank: " + i);
            if (i == 6) {
                try {
                    rank.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }// catch
            }// if

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }// catch

        }// for
    }// synchronized

}// run

}

Passenger.java

package multhithreading.engage.hireForHier;

public class Passenger implements Runnable {

Rank rank = null;

public Passenger(Rank rank) {
    this.rank = rank;
}

public void run() {
    System.out.println(Thread.currentThread().getName() + "  Destined for rank No. " + rank.getRankNo());

    synchronized (rank) {

        for (int i = 1; i < 10; i++) {

            System.out.println("Passenger has reached rank: " + i);
            if (i == 6) {
                notify();

            }// if
            try {
                Thread.sleep(180);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }// catch

        }// for
    }// synchronized

}// run
}

Rank.java

package multhithreading.engage.hireForHier;


public class Rank {

private int rankNo = 0;

public Rank(int rankNo) {
    this.rankNo = rankNo;
}

public int getRankNo() {
    return rankNo;
}
}

TaxiHire.java

package multhithreading.engage.hireForHier;

public class TaxiHire {

public static void main(String[] args) {

    Rank rank6 = new Rank(6);

    Taxi taxiNo3 = new Taxi(rank6);
    Passenger passengerNo3 = new Passenger(rank6);

    Thread taxi_thread = new Thread(taxiNo3, "taxi_thread");

    Thread passenger_thread = new Thread(passengerNo3, "passenger_thread");

    taxi_thread.start();
    passenger_thread.start();
}

}

我得到的输出是:

taxi_thread  Destined for rank No. 6
Taxi has reached rank: 1
passenger_thread  Destined for rank No. 6
Taxi has reached rank: 2
Taxi has reached rank: 3
Taxi has reached rank: 4
Taxi has reached rank: 5
Taxi has reached rank: 6
Passenger has reached rank: 1
Passenger has reached rank: 2
Passenger has reached rank: 3
Passenger has reached rank: 4
Passenger has reached rank: 5
Passenger has reached rank: 6
Exception in thread "passenger_thread" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at lesson9.engage.hireForHier.Passenger.run(Passenger.java:20)
    at java.lang.Thread.run(Unknown Source)

我需要知道为什么会抛出异常,对我而言,看起来Taxi线程没有回到锁定状态。 如何实施这种情况以及出租车线程如何继续循环。

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

错误在Passenger类中,您同步rand对象但通知此对象 所以你的代码是

if (i == 6) {
                notify();

            }// if

应该是

if (i == 6) {
                try{rank.notify();
                }catch(Exception ex){/*When no any thread is waiting for rank object.*/}

            }// if

也有可能出租车线程首先出现,所以在这里你也会遇到异常,因为没有任何线程在等待等级对象。

首先启动出租车线程,然后启动乘客,最可靠的方法是用出租车线程呼叫乘客线程。它确保您的出租车线程先行。

link可能会帮助您解决可能的情况。

答案 1 :(得分:1)

if (i == 6) {
   notify();

此处您没有调用rank.notify(),因此默认行为将尝试调用this对象Passenger对象)上的通知,这将引发{ {1}}因为你没有锁定IllegalMonitorStateException

  当您尝试thisIllegalMonitorStateExceptionwait()时,会出现

notify()   在没有锁定该对象的对象上。

<强>解决方案:

notifyAll()