无法理解多线程代码的执行流程

时间:2015-06-05 14:52:00

标签: java multithreading

我在我的应用程序中发现了这种代码,并且我在不同的时间获得了不同的输出。我很迷惑。请告诉我代码的可能执行流程。感谢。

import java.util.Vector;

class Producer extends Thread {

 static final int MAXQUEUE = 5;
 private Vector messages = new Vector();

 @Override
 public void run() {
     try {
         while (true) {
            putMessage();
            //sleep(5000);
         }
     } catch (InterruptedException e) {
     }
 }

 private synchronized void putMessage() throws InterruptedException {
     while (messages.size() == MAXQUEUE) {
        wait();
     }
     messages.addElement(new java.util.Date().toString());
     System.out.println("put message");
     notify();
     //Later, when the necessary event happens, the thread that is     running it calls notify() from a block synchronized on the same object.
 }

 // Called by Consumer
 public synchronized String getMessage() throws InterruptedException {
     notify();
     while (messages.size() == 0) {
         wait();//By executing wait() from a synchronized block, a thread  gives up its hold on the lock and goes to sleep.
     }
     String message = (String) messages.firstElement();
     messages.removeElement(message);
     return message;
  }
 }



class Consumer extends Thread {

 Producer producer;

 Consumer(Producer p) {
    producer = p;
 }

 @Override
 public void run() {
     try {
         while (true) {
            String message = producer.getMessage();
            System.out.println("Got message: " + message);
            //sleep(200);
         }
     } catch (InterruptedException e) {
         e.printStackTrace();
     }
 }

 public static void main(String args[]) {
    Producer producer = new Producer();
    producer.start();
    new Consumer(producer).start();
 }
}

请通过几个步骤告诉可能的执行流程。非常感谢。

2 个答案:

答案 0 :(得分:1)

当涉及到"当前日期或时间"时,它意味着"随机性"。您的代码输出不同的原因不是多线程,而是

new java.util.Date() 

线程切换也会导致随机性,但由于存在锁定,因此很容易避免。您的代码也可以使用JAVA关键字" synchronized"关于方法。当一个方法有一个" synchronized"时,等于你正在使用

synchronized(this) {...}

这意味着不同的线程不能同时运行到同一个Producer对象{...}中。生产者在将一个ele放到vector之后调用notify(),这意味着生产者说"向量不是空的,请从中获取一些东西"消费者。消费者从向量中获取一个ele之后调用notify(),这意味着消费者说"向量未满,请将你的ele放入其中#34;生产者。

要清楚地了解这些事情,请学习JAVA中锁和条件的基础知识。

答案 1 :(得分:0)

执行多个线程可能会为同一输入提供不同的输出以便重复执行。只要生成的消息量不超过最大队列大小,并且消费者通过将消息打印出来并将消息从队列中删除(只要队列不为空),此代码就会生成生成器“生成”消息。

生产者 - 消费者问题非常受欢迎,对于理解线程如何同步工作非常重要。查看此文章以获取进一步说明:http://ankitsambyal.blogspot.com/2014/02/mutex-in-java-explained-using-producer.html

希望这有帮助!