我正在尝试编写一个使用线程的Java程序。我希望能够在程序启动时运行3个线程,并让它们等待“工作订单”的ArrayList。 最初,这将是没有工作订单。所以线程应该等待。 在将来的某个时刻,工作订单将被添加到ArrayList,主线程必须通知线程有工作要做。
我希望能够通过扩展Thread(而不是实现Runnable)来实现。
我认为我遇到的主要问题是线程未与工作组ArrayList正确同步。
我的代码如下所示:
public static void main(String[] args) {
AnotherRunnable anotherRunnable = new AnotherRunnable();
ArrayList<ATMRunnable> workOrders = new ArrayList<ATMRunnable>();
T1 t1 = new T1(anotherRunnable, workOrders);
T1 t2 = new T1(anotherRunnable, workOrders);
t1.start();
t2.start();
try{
Thread.sleep(2000);
}
catch(InterruptedException e){}
synchronized (workOrders){
System.out.println(t1.getState() + " - " + t1.getName());
System.out.println(t2.getState() + " - " + t2.getName());
System.out.println("notify");
workOrders.notify();
System.out.println(t1.getState() + " - " + t1.getName());
System.out.println(t2.getState() + " - " + t2.getName());
}
}
AnotherRunnable类:
public class AnotherRunnable implements Runnable {
public void run()
{
System.out.println("AnotherRunnable");
}
}
和Tread课程:
公共类T1扩展了线程{
AnotherRunnable anotherRunnable;
ArrayList<ATMRunnable> workOrders;
ATMThread(AnotherRunnable anotherRunnable, ArrayList<ATMRunnable> workOrders)
{
this.anotherRunnable = anotherRunnable;
this.workOrders = workOrders;
}
public void run()
{
System.out.println("Run Thread");
synchronized (workOrders){
try{
System.out.println("wait Thread");
workOrders.wait();
}
catch (InterruptedException e){}
}
}
}
这是该计划的输出:
Run Thread
wait Thread
Run Thread
wait Thread
WAITING - Thread-1
WAITING - Thread-2
notify all
BLOCKED - Thread-1
WAITING - Thread-2
正如您所看到的,在对workOrders对象进行通知调用之后,第一个线程的状态将更改为“已阻止”。但是线程和runnable对象都没有被执行。
任何帮助将不胜感激。
答案 0 :(得分:0)
您应该在java中使用并发集合,以尽可能避免手动同步。
我希望能够在程序启动时运行3个线程,让它们等待“工作订单”的ArrayList。最初,这将是没有工作订单。所以线程应该等待。在将来的某个时刻,工作订单将被添加到ArrayList,主线程必须通知线程有工作要做。
对于这种同步,Blocking queues是你的朋友,如LinkedBlockingQueue,当队列中没有项目或队列已满时,线程会等待。你不需要任何同步/等待/通知。
您还可以检查它是否有帮助:synchronization is risky
如果仅用于学习目的,则必须首先在逻辑上使您的同步正确。它不会使用任何条件来等待或通知哪些是有问题的。如果它是正确的,它将起作用,但它不是一种优选的方式。
答案 1 :(得分:0)
我发现我必须做些什么才能让这个工作。主要是缺少的概念。我不得不循环线程的run方法。我想每次调用notifyall时都会调用该方法,但事实并非如此。当在同步对象上调用wait()时,线程停止,并且通知它恢复执行,如果该代码不在循环中,则不会执行。