简体   繁体   中英

Java Thread concept / demo

I'm trying to write a Java program that uses threads. I want to be able to run 3 threads when the program starts, and have them waiting on an ArrayList of "work orders". Initially, theere will be no work orders. So the Threads should just wait. At some point in the future, work orders will be added to the ArrayList, and the main thread must notify the threads that there is work to do.

I want to be able to do it by extending Thread (instead of implementing Runnable).

I think the main issue I have is that the threads are not correctly synchronized with the workorders ArrayList.

My code looks like this:

  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());

    }
  }

The AnotherRunnable class:

public class AnotherRunnable implements Runnable {

public void run()
{
    System.out.println("AnotherRunnable");

}
}

And the Tread class:

public class T1 extends 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){}
    }

}

}

This is the output of the program:

Run Thread
wait Thread
Run Thread
wait Thread
WAITING - Thread-1
WAITING - Thread-2
notify all
BLOCKED - Thread-1
WAITING - Thread-2

As you can see, the state of the first thread is changed to Blocked, after the call to notify on the workOrders object. But neither the threads nor the runnable object is executed.

Any help will be appreciated.

You should use concurrent collections in java to avoid manual synchronization as far as possible.

I want to be able to run 3 threads when the program starts, and have them waiting on an ArrayList of "work orders". Initially, theere will be no work orders. So the Threads should just wait. At some point in the future, work orders will be added to the ArrayList, and the main thread must notify the threads that there is work to do.

For this kind of synchronization, Blocking queues are your friends like LinkedBlockingQueue which make threads wait when there's no item in the queue or when the queue is full. You do not need any synchronized/wait/notify there.

You can also check if it helps: synchronization is risky

If it is only for learning purpose, you have to make your synchronization proper first logically. It doesn't use any condition for waiting or notifying which is problematic. It'll work if it is proper but its not a preferred way.

I found what I had to do to get this working. Mainly, it was the concept what was missing. I had to loop in the run method of the thread. I was thinking that that method would be called every time notifyall is invoked, which is not true. When wait() is call on the synchronized object, the thread is stopped, and with notify it resumes execution, if that code is not in a loop, it wont be executed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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