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

标签 java multithreading concurrency

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

我想出了一个小项目,我试图用多线程来解决它。 我有一辆出租车,将达到 Rank 6,我有一名乘客,将达到 Rank6。

出租车将比乘客先到达 6 级,并 wait() 等待乘客。 当Passenger达到Rank6时,他将notify()

收到通知后,该出租车将继续循环,不会进入其他队列。

出租车.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 线程似乎没有取回锁。 这个场景应该如何实现以及Taxi线程如何继续循环。

我们将非常感谢您的帮助。

最佳答案

错误发生在 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可能会帮助您解决可能的情况。

关于java - 在多线程中使用wait()和notify(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19421682/

相关文章:

java - 如何在JasperReports中使用Map作为数据集元素?

java - Apache MiNiFi 与 jre-1.7 的兼容性

java - 无法在android中使用Retrofit和Java创建POJO

ios - 最高效的线程实现IOS

multithreading - ColdFusion/Railo 组件线程化 http 请求

java - 更改 jax-rs REST 服务中的内容类型

java - 多线程多 channel 发布时线程全部被阻塞,rabbitmq

java - 最终改变的属性

java - Swing:将值从预定线程传回 UI

java - 将 "init"中定义的 servlet 实例变量标记为 "volatile"