如何使两个线程等待并相互通知

时间:2013-12-16 15:47:31

标签: java multithreading

我必须创建两个Threads,它们必须以2秒的间隔从队列中进行轮询和对象。

第一个Thread轮询和对象然后等待并通知第二个轮询从该队列中轮询该对象。

我读了所有关于等待和通知的内容,但没有任何关系。

任何sugestions?

第一个帖子:

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

}

第二个帖子:

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


}

}

2 个答案:

答案 0 :(得分:1)

您基本上想要实现的是一个系统,它在两个独立单元之间交替控制,以便每个单元都有一些时间来处理,然后是两秒钟的等待时间(反之亦然)。

有两种主要方法可以实现这一目标:

  1. 使用中央控制
  2. 使用自主沟通代理
  3. 第一种方法更容易一些。在这里,您有一个中央“主”组件,负责协调谁获得处理时间并实现等待时间。对于这种方法,两个独立单元甚至不必是线程:

    public class South {
        private Queue<Car> q = new LinkedList<Car>();
    
        public void CreateQueue() { ... }
    
        public void poll() {
            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.");
        }
    }
    
    public class North {
        private Queue<Car> q = new LinkedList<Car>();
    
        public void CreateQueue() { ... }
    
        public void poll() {
            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 is the "master" class
    public class Main {
        public static void main(String[] args) {
            South south = new South();
            North north = new North();
    
            south.CreateQueue();
            north.CreateQueue();
    
            boolean done = false;
            while (!done) {
                try {
                    Thread.sleep(2000);
                } (catch InterruptedException) { /* TODO */ }
    
                north.poll();
    
                try {
                    Thread.sleep(2000);
                } (catch InterruptedException) { /* TODO */ }
    
                south.poll();
            }
        }
    }
    

    请注意,北方和南方不会从Thread继承,即它们只是普通的旧对象。 (但是,如果你的程序更复杂并且North / South只是其中的一部分,你可能想让Main(!)成为一个单独的线程并将上面的while循环放在线程的run方法中,所以程序的其余部分可以同时运行。)

    在第二种方法中,您没有这样的中央控制组件,但是北方和南方都在它们自己的单独线程中运行。这就要求他们通过相互沟通来协调谁被允许处理。

    public class SouthThread extends Thread {
        protected Queue<Car> q = new LinkedList<Car>();
        protected North north;
    
        public void CreateQueue() { ... }
        public void poll() { ... }
    
        public void run() {
            boolean done = false;
            while (!done) {
                // wait two seconds
                try {
                    Thread.sleep(2000);
                } (catch InterruptedException) { /* TODO */ }
    
                // process one element from the queue
                poll();
    
                // notify the other thread
                synchronized (north) {
                    north.notifyAll();
                }
    
                // wait until the other thread notifies this one
                try {
                    synchronized (this) {
                        wait();
                    }
                } (catch InterruptedException) { /* TODO */ }
            }
        }
    }
    
    public class NorthThread extends Thread {
        protected Queue<Car> q = new LinkedList<Car>();
        protected South south;
    
        public void CreateQueue() { ... }
        public void poll() { ... }
    
        public void run() {
            boolean done = false;
            while (!done) {
                // wait two seconds
                try {
                    Thread.sleep(2000);
                } (catch InterruptedException) { /* TODO */ }
    
                // process one element from the queue
                poll();
    
                // notify the other thread
                synchronized (south) {
                    south.notifyAll();
                }
    
                // wait until the other thread notifies this one
                try {
                    synchronized (this) {
                        wait();
                    }
                } (catch InterruptedException) { /* TODO */ }
            }
        }
    }
    
    public class Main {
        public static void main(String[] args) throws Exception {
            SouthThread tSouthThread = new SouthThread();
            NorthThread tNorthThread = new NorthThread();
    
            tSouthThread.north = tNorthThread;
            tNorthThread.south = tSouthThread;
    
            tSouthThread.CreateQueue();
            tNorthThread.CreateQueue();
    
            tSouthThread.start();
            tNorthThread.start();    
        }
    }
    

    更一般的评论:由于北方和南方似乎基本相同,因此可能不需要在两个单独的类中实现它们。相反,只有一个实现所需功能的类并将其实例化两次就足够了:

    // We can combine the functionality of North and South 
    // in a single class
    public class NorthSouth {
        public void CreateQueue() { ... }
        public void poll() { ... }
    
        // etc.
    }
    
    public class Main {
        public static void main(String[] args) {
            NorthSouth north = new NorthSouth();
            NorthSouth south = new NorthSouth();
    
            north.CreateQueue();
            south.CreateQueue();
    
            // etc.
        }
    }
    

答案 1 :(得分:0)

waitnotify必须引用相同的锁定:当您拨打object.wait(2000)时,您说的是&#34;我会在这里等对于2000毫秒,或直到其他人致电object.notify(),其中object指的是&#34;

我仍然不完全理解你想要达到的目标,但如果你只是想要同时做两个线程:

  1. 做点什么
  2. 等待2秒
  3. GOTO 1
  4. 那么你根本不需要等待/通知,你可以使用Thread.sleep()或可能有两个java.util.Timer个实例。

    但是,我不确定我是否理解正确。 : - (