2013-05-12 109 views
0

我正在尝试编写一个使用线程的Java程序。我希望能够在程序启动时运行3个线程,并让他们在“工单”的ArrayList上等待。 最初,这将是没有工作订单。所以线程应该等待。 在未来的某个时间点,工作订单将被添加到ArrayList中,并且主线程必须通知线程有工作要做。Java线程概念/演示

我想通过扩展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"); 

} 
} 

和胎面类:

公共类T1继承Thread {

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 

正如你所看到的,第一个线程的状态改变到阻止,后电话通知的工作订单对象。但是线程和可运行对象都不会被执行。

任何帮助将不胜感激。

+2

有相当多的问题 - 其中之一是,你永远不会调用'anotherRunnable.run()',所以也没有办法,你可以看到'AnotherRunnable'印刷......你也叫'notify',不' notifyAll',所以只有一个线程被唤醒。 – assylias 2013-05-12 18:47:12

+0

@assylias线程调用'开始()'方法开始。 'run()'不应该从程序员代码中调用。 – SJuan76 2013-05-12 18:48:14

+0

@ SJuan76除了'线程#run'方法已被重写,所以'Runnable'的'run'方法不会被调用。 – assylias 2013-05-12 18:48:54

回答

0

我发现我必须做的才能让它工作。主要是,这是缺少的概念。我不得不循环线程的运行方法。我在想每次调用notifyall时都会调用这个方法,这是不正确的。当对同步对象调用wait()时,该线程将停止,并且如果该代码不在循环中,则会继续执行,但不会执行。

0

您应该在java中使用并发集合以尽可能避免手动同步。

我希望能够在程序启动时运行3个线程,并让他们在“工作订单”的ArrayList上等待。最初,这将是没有工作单。所以线程应该等待。在将来的某个时间点,工作订单将被添加到ArrayList中,并且主线程必须通知线程有工作要做。

对于这种同步的,Blocking queues是你的朋友喜欢LinkedBlockingQueue这使得线程等待时,有队列,或者当队列已满没有项目。你不需要任何同步/等待/通知。

您还可以检查是否有帮助:synchronization is risky

如果只是用于学习目的,你必须让你同步正确先从逻辑。它没有使用任何条件来等待或通知哪些是有问题的。它会工作,如果它是适当的,但它不是一个首选的方式。

+0

谢谢。我希望能够手动完成,而不需要LinkedBlockingQueue。这只是一个理论练习。我需要理解为什么,在线程上运行没有被调用。那是因为我在ArrayList上同步的方式吗? – oscarm 2013-05-13 16:45:21