简体   繁体   English

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

[英]Using wait() and notify() in multithreading

I am trying wait() , and notify() methods for multi-threading. 我正在尝试wait()notify()方法进行多线程处理。

I have come up with a small project which I am trying to solve with multi-threading. 我想出了一个小项目,我试图通过多线程解决。 I have a Taxi, that will reach Rank 6, and I have a Passenger that will reach Rank6. 我有一辆出租车,将达到等级6,我有一辆乘客将达到Rank6。

Taxi will arrive at Rank 6 earlier that Passenger and will wait() for Passenger. 出租车将在乘客之前到达等级6,并将wait()乘客。 When Passenger reaches Rank6, he will notify() . 当乘客到达Rank6时,他会notify()

After getting notified, that Taxi, will continue with the loop and will no to other Ranks. 在收到通知后,该出租车将继续循环并且不会对其他排名。

Taxi.java 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 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 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 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();
}

}

The output I am getting is: 我得到的输出是:

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)

I need to know why the exception is getting thrown, to me it looks like that the Taxi thread is not getting back the lock. 我需要知道为什么异常会被抛出,对我而言,看起来Taxi线程没有回到锁定状态。 How should this scenario be implemented and how can Taxi thread continue with the loop. 如何实现这种情况以及Taxi线程如何继续循环。

Your help will really be appreciated. 非常感谢您的帮助。

The error is in Passenger class, you synchronize the rand object but notify this object so you code is 错误在Passenger类中,您同步rand对象但通知此对象,因此您编写代码

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

            }// if

and should be 应该是

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

            }// if

also this is possible that taxi thread goes first, so here you will face with exception too, because no any thread is waiting for rank object. 也许这可能是出租车线程先行,所以在这里你也将面临异常,因为没有任何线程在等待等级对象。

so start the taxi thread first, then start the passenger, the best reliable approach is calling passenger thread with taxi thread. 所以首先启动出租车线程,然后启动乘客,最可靠的方法是用出租车线程呼叫客运线程。 it ensures you taxi thread goes first. 它确保您的出租车线程先行。

this link may help you with possible situation. 链接可能会帮助您解决可能的情况。

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

Here you are not calling rank.notify() , so the default behavior will try to call notify on this object ( Passenger Object), which will throw IllegalMonitorStateException as you dont hold lock on this 这里你没有调用rank.notify() ,所以默认行为将尝试this对象Passenger Object) 上调用notify ,这将抛出IllegalMonitorStateException因为你没有锁定this

IllegalMonitorStateException occurs when you try to wait() or notify() or notifyAll() on an object without holding lock on that object. 当您尝试对某个对象上的wait()notify()notifyAll()而不保持对该对象的锁定时,会发生IllegalMonitorStateException

Solution: 解:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM