Java 如何使两个线程等待并相互通知
我必须创建两个线程,这两个线程必须在2秒钟的时间间隔内从队列中轮询和对象 第一个线程轮询对象,然后等待并通知第二个线程轮询其队列中的对象 我读了所有关于等待和通知的书,但都不适合我 有什么建议吗 第一个线程:Java 如何使两个线程等待并相互通知,java,multithreading,Java,Multithreading,我必须创建两个线程,这两个线程必须在2秒钟的时间间隔内从队列中轮询和对象 第一个线程轮询对象,然后等待并通知第二个线程轮询其队列中的对象 我读了所有关于等待和通知的书,但都不适合我 有什么建议吗 第一个线程: public class SouthThread extends Thread { private Queue<Car> q = new LinkedList<Car>(); public void CreateQueue() { Scanner in
public class SouthThread extends Thread {
private Queue<Car> q = new LinkedList<Car>();
public void CreateQueue() {
Scanner input = new Scanner(System.in);
for (int i = 0; i < 2; i++) {
Car c = new Car();
System.out.println("Enter registration number: ");
String regNum = input.nextLine();
c.setRegNum(regNum);
q.offer(c);
}
}
public int getQueueSize() {
return q.size();
}
@Override
public void run() {
while (q.size() != 0)
try {
while (q.size() != 0) {
synchronized (this) {
System.out.print("The car with registration number: ");
System.out.print(q.poll().getRegNum());
System.out
.println(" have passed the bridge from the south side.");
this.wait(2000);
notify();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
wait
和notify
必须引用同一个锁:当你调用对象时。wait(2000)
你说的是“我将在这里等待2000毫秒,或者直到其他人调用对象。notify()
对象指我的地方”
我仍然不完全理解您想要实现什么,但是如果您只是想要两个线程同时执行以下操作:
做点什么
等2秒钟
转到1
然后,您根本不需要等待/通知,您可以使用Thread.sleep()
或java.util.Timer
的两个实例
但是,我不确定我是否理解正确-(似乎您基本上想要实现的是一个系统,它在两个独立的单元之间交替控制,以便每个单元都有一段时间来处理,然后是两秒钟的等待期(反之亦然)
有两种主要方法可以实现这一点:
使用中央控制
使用自主通信代理
第一种方法比较简单。这里有一个中央“主”组件,负责协调谁获得处理时间,并实现等待时间。对于这种方法,两个独立的单元甚至不必是线程:
public class-South{
private Queue q=new LinkedList();
public void CreateQueue(){…}
公众投票{
系统输出打印(“登记号为:”)的汽车;
System.out.print(q.poll().getRegNum());
System.out.println(“已经从南侧通过了桥”);
}
}
公共舱北{
private Queue q=new LinkedList();
public void CreateQueue(){…}
公众投票{
系统输出打印(“登记号为:”)的汽车;
System.out.print(q.poll().getRegNum());
System.out.println(“从北侧通过了桥”);
}
}
//这是“大师”班
公共班机{
公共静态void main(字符串[]args){
南南=新南();
北北=新北();
south.CreateQueue();
CreateQueue();
布尔完成=假;
而(!完成){
试一试{
《睡眠》(2000年);
}(捕获中断异常){/*TODO*/}
north.poll();
试一试{
《睡眠》(2000年);
}(捕获中断异常){/*TODO*/}
south.poll();
}
}
}
请注意,这里的North和South并不继承自线程
,也就是说,它们只是普通的旧对象。
(但是,如果您的程序更复杂,并且南北方向只是其中的一部分,那么您可能希望将Main(!)作为一个单独的线程,并将上面的while循环放在线程的run
方法中,以便程序的其余部分可以同时运行。)
在第二种方法中,您没有这样的中央控制组件,但是北方和南方都在各自独立的线程中运行。这就要求它们通过相互通信来协调允许谁进行处理
公共类SouthThread扩展线程{
受保护队列q=新的LinkedList();
受保护的北方;
public void CreateQueue(){…}
public void poll(){…}
公开募捐{
布尔完成=假;
而(!完成){
//等两秒钟
试一试{
《睡眠》(2000年);
}(捕获中断异常){/*TODO*/}
//处理队列中的一个元素
poll();
//通知另一个线程
同步(北){
north.notifyAll();
}
//等待另一个线程通知这个线程
试一试{
已同步(此){
等待();
}
}(捕获中断异常){/*TODO*/}
}
}
}
公共类NorthThread扩展线程{
受保护队列q=新的LinkedList();
南南保护;
public void CreateQueue(){…}
public void poll(){…}
公开募捐{
布尔完成=假;
而(!完成){
//等两秒钟
试一试{
《睡眠》(2000年);
}(捕获中断异常){/*TODO*/}
//处理队列中的一个元素
poll();
//通知另一个线程
(南部){
south.notifyAll();
}
//等待另一个线程通知这个线程
试一试{
已同步(此){
等待();
}
}(捕获中断异常){/*TODO*/}
}
}
}
公共班机{
公共静态void main(字符串[]args)引发异常{
SouthThread tSouthThread=新的SouthThread();
NorthThread tNorthThread=新的NorthThread();
tSouthThread.north=tnothread;
tnothread.south=tSouthThread;
tSouthThread.CreateQueue();
tNorthThread.CreateQueue();
tSouthThread.start();
tnothread.start();
}
}
更一般的一句话:由于北方和南方的做法似乎基本相同,因此可能不需要在两个单独的类中实现它们。相反,只有一个类实现所需的功能并实例化两次就足够了:
//我们可以将North和Sout的功能结合起来
public class NorthThread extends Thread {
private Queue<Car> q = new LinkedList<Car>();
public void CreateQueue() {
Scanner input = new Scanner(System.in);
for (int i = 0; i < 2; i++) {
Car c = new Car();
System.out.println("Enter registration number: ");
String regNum = input.nextLine();
c.setRegNum(regNum);
q.offer(c);
}
}
public int getQueueSize() {
return q.size();
}
@Override
public void run() {
try {
while (q.size() != 0) {
synchronized (this) {
System.out.print("The car with registration number: ");
System.out.print(q.poll().getRegNum());
System.out
.println(" have passed the bridge from the north side.");
this.wait(2000);
notify();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public class Main {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
SouthThread tSouthThread = new SouthThread();
NorthThread tNorthThread = new NorthThread();
tSouthThread.CreateQueue();
tNorthThread.CreateQueue();
System.out.println(tSouthThread.getQueueSize());
tSouthThread.start();
tNorthThread.start();
}