为什么 Consumer 线程无法从 Vector 中删除消息?
Why Consumer thread is not able to remove messages from Vector?
我正在尝试为生产者/消费者问题创建一个解决方案,其中一个线程将消息放入 Vector 而另一个线程从中删除。
import java.util.Vector;
public class Producer implements Runnable {
static final int MAXQUEUE = 5;
private Vector<String> messages;
public Producer(Vector<String> messages) {
super();
this.messages = messages;
}
@Override
public void run() {
try {
while (true)
putMessage();
} 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");
notifyAll();
}
public static void main(String args[]) {
Vector<String> messages = new Vector<String>();
new Thread(new Producer(messages)).start();
new Thread(new Consumer(messages)).start();
}
}
class Consumer implements Runnable{
public Consumer(Vector<String> messages) {
super();
this.messages = messages;
}
private Vector<String> messages;
public synchronized String getMessage() throws InterruptedException {
notifyAll();
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;
}
@Override
public void run() {
try {
while (true) {
String message = getMessage();
System.out.println("Got message: " + message);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
每当我 运行 程序时,它都会打印 put 消息 5 次。即使在 notifyAll() 之后我也不明白,它没有给消费者锁。
登录到控制台非常慢,因此如果您在不持有锁的情况下执行此操作,您就给了消费者一个机会。
@Override
public void run() {
try {
while (true) {
// slows the producer a little to give the consumer a chance to get the lock.
System.out.println("put message");
putMessage();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void putMessage() throws InterruptedException {
synchronized (messages) {
while (messages.size() == MAXQUEUE) {
messages.wait();
}
messages.addElement(new java.util.Date().toString());
messages.notifyAll();
}
}
顺便说一句,消费者可以这样写
public String getMessage() throws InterruptedException {
synchronized (messages) {
while (messages.isEmpty()) {
messages.wait();//By executing wait() from a synchronized block, a thread gives up its hold on the lock and goes to sleep.
}
messages.notifyAll();
return messages.remove(0);
}
}
您的代码无法正常工作,因为您的两个线程未 notifying/waiting 在同一监视器上。
他们每个人都在自己的监视器上通知和等待,而不是共享监视器。更改代码以使用共享监视器,例如messages
,包括同步。
private void putMessage() throws InterruptedException {
synchronized (messages) { // <======
while (messages.size() == MAXQUEUE) {
messages.wait(); // <======
}
messages.addElement(new java.util.Date().toString());
System.out.println("put message");
messages.notifyAll(); // <======
}
}
public String getMessage() throws InterruptedException {
synchronized (messages) { // <======
while (messages.size() == 0) {
messages.wait(); // <======
}
String message = (String) messages.firstElement();
messages.removeElement(message);
messages.notifyAll(); // <======
return message;
}
}
注意方法不再同步。
我正在尝试为生产者/消费者问题创建一个解决方案,其中一个线程将消息放入 Vector 而另一个线程从中删除。
import java.util.Vector;
public class Producer implements Runnable {
static final int MAXQUEUE = 5;
private Vector<String> messages;
public Producer(Vector<String> messages) {
super();
this.messages = messages;
}
@Override
public void run() {
try {
while (true)
putMessage();
} 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");
notifyAll();
}
public static void main(String args[]) {
Vector<String> messages = new Vector<String>();
new Thread(new Producer(messages)).start();
new Thread(new Consumer(messages)).start();
}
}
class Consumer implements Runnable{
public Consumer(Vector<String> messages) {
super();
this.messages = messages;
}
private Vector<String> messages;
public synchronized String getMessage() throws InterruptedException {
notifyAll();
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;
}
@Override
public void run() {
try {
while (true) {
String message = getMessage();
System.out.println("Got message: " + message);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
每当我 运行 程序时,它都会打印 put 消息 5 次。即使在 notifyAll() 之后我也不明白,它没有给消费者锁。
登录到控制台非常慢,因此如果您在不持有锁的情况下执行此操作,您就给了消费者一个机会。
@Override
public void run() {
try {
while (true) {
// slows the producer a little to give the consumer a chance to get the lock.
System.out.println("put message");
putMessage();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void putMessage() throws InterruptedException {
synchronized (messages) {
while (messages.size() == MAXQUEUE) {
messages.wait();
}
messages.addElement(new java.util.Date().toString());
messages.notifyAll();
}
}
顺便说一句,消费者可以这样写
public String getMessage() throws InterruptedException {
synchronized (messages) {
while (messages.isEmpty()) {
messages.wait();//By executing wait() from a synchronized block, a thread gives up its hold on the lock and goes to sleep.
}
messages.notifyAll();
return messages.remove(0);
}
}
您的代码无法正常工作,因为您的两个线程未 notifying/waiting 在同一监视器上。
他们每个人都在自己的监视器上通知和等待,而不是共享监视器。更改代码以使用共享监视器,例如messages
,包括同步。
private void putMessage() throws InterruptedException {
synchronized (messages) { // <======
while (messages.size() == MAXQUEUE) {
messages.wait(); // <======
}
messages.addElement(new java.util.Date().toString());
System.out.println("put message");
messages.notifyAll(); // <======
}
}
public String getMessage() throws InterruptedException {
synchronized (messages) { // <======
while (messages.size() == 0) {
messages.wait(); // <======
}
String message = (String) messages.firstElement();
messages.removeElement(message);
messages.notifyAll(); // <======
return message;
}
}
注意方法不再同步。