java - 了解JAVA中的同步方法

标签 java multithreading

我是JAVA新手,正在学习JAVA中的多线程。这是我的代码片段。

import java.util.*;
import java.lang.*;
import java.io.*;

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

    public synchronized void putMessage() throws InterruptedException {
        while (messages.size() == MAXQUEUE) {
            System.out.println("waiting for space in queue ");
            wait();
        }
        messages.addElement(new java.util.Date().toString());
        System.out.println("created a new message and message count is " + messages.size());
        notify();
    }

    public synchronized String getMessage() throws InterruptedException {
        notify();
        while (messages.size() == 0) {
            System.out.println("queue is empty ");
            wait();
        }
        String message = (String) messages.firstElement();
        messages.removeElement(message);
        System.out.println("removed a message and message count is " + messages.size());
        return message;
    }
}

class Producer extends Thread {
    Manager myRef;

    Producer(Manager ref) {
        myRef = ref;
    }

    public void run() {
        try {
            while (true) {
                myRef.putMessage();
                sleep(1000);
            }
        } catch (InterruptedException e) {
        }
    }
}

class Consumer extends Thread {
    Manager myRef;

    Consumer(Manager ref) {
        myRef = ref;
    }

    public void run() {
        try {
            while (true) {
                String message = myRef.getMessage();
                System.out.println("Got message: " + message);
                sleep(2000);
            }
        } catch (InterruptedException e) {
        }
    }

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

我的期望:

  1. 首先,我的 Producer 线程将控制 Manager 对象上的锁。它将调用 putMessage() 直到计数达到 5,然后释放锁。
  2. 现在消费者线程将获取锁并开始读取消息,直到列表为空,然后释放锁。 这个序列将继续下去。

但是,发生了什么:

created a new message and message count is 1
removed a message and message count is 0
Got message: Thu Aug 13 07:26:45 GMT 2015
created a new message and message count is 1
removed a message and message count is 0
Got message: Thu Aug 13 07:26:46 GMT 2015
and so on.....
正如您所看到的,即使管理器对象的锁位于正在执行 putMessage() 的生产者线程中,我的消费者线程也能够调用 readMessage()。如果一个线程正在执行一个实例方法,其他线程如何调用另一个实例方法?

请纠正我的理解。

最佳答案

首先,您的生产者线程执行 putMessage 方法。他创建了一项并将其添加到 messages 列表中。当 putMessage 完成并创建一项时,生产者线程将进入休眠状态。

当消费者线程醒来时,他可以自由地访问getMessage方法并消费唯一的项目。然后消费者就去 sleep 了。

这个过程一直重复。正如您所期望的,synchronized 关键字可以防止一个对象的任何同步方法可以并行执行。正如我所解释的那样,这并没有发生。线程只是交替访问方法。每个方法调用只会生成或消耗一项。

关于java - 了解JAVA中的同步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31982478/

相关文章:

java - 软键盘在横向模式下不会自动显示

c++ - 高效读取共享资源

java - 使用线程实时更新 JTextArea

java - 访问自定义线程方法

c++ - 为什么投长可以解决 "warning: cast to pointer from integer of different size"?

java - JDO @ DataNucleus 中的无限字符串? (H2 数据库)

java - 我可以使用 BCEL 将注释添加到我的 java 类中吗?

java - 如何将 Maven 库依赖项的版本打印到控制台

java - 我们可以将多个参数传递给 RestCypherQueryEngine.query 吗?

java - Runtime.exec().waitFor() 实际上并不是在等待