我有这种情况:
class MyClass {
Producer p;
Consumer c;
public static void main(String[] args){
BlockingQueue q = new LinkedBlockingQueue();
p = new Producer(q);
c = new Consumer(q);
Thread t = new Thread(p);
t.start();
new Thread(c).start();
while (true) {
if (!p.getContinuer()) {
c.setContinuer(false);
System.out.println("here:"+p.getContinuer().toString());
break;
}
}
System.out.println("finish all");
}
}
class Producer implements Runnable {
private final BlockingQueue queue;
private AtomicBoolean continuer = new AtomicBoolean(true);
public Boolean getContinuer() {
return continuer.get();
}
@Override
public void run() {
while(true){
//open socket
//read data from socket
queue.put(data);
if(end){
System.out.println("Shutting down Producer");
continuer.getAndSet(false);
}
}
}
}
class Consumer implements Runnable {
private final BlockingQueue queue;
private static AtomicBoolean continuer = new AtomicBoolean(true);
public void setContinuer(Boolean continuerr) {
continuer = new AtomicBoolean(continuerr);
}
public Boolean getContinuer() {
return continuer.get();
}
@Override
public void run() {
while (getContinuer()) {
//Do some work
consume(queue.take());
}
System.out.println("shut down Consumer");
}
}
这就是我得到的:
关闭制作人
这里:假
完成所有
这意味着消费者仍在工作,变量“continuer”不会更新。
我也看到了this和this帖子,我试过了,但没有任何改变。
我的问题是什么?
编辑:我改变了我的代码,显然消费者在尝试从waiting if no elements are present on this queue. 读取数据时被阻止(BlockingQueue)(参见consume(queue.take()); in消费者类)。
答案 0 :(得分:3)
那么,
public void setContinuer(Boolean continuerr) {
continuer = new AtomicBoolean(continuerr);
}
看起来不对。你为什么不
public void setContinuer(boolean continuerr) {
continuer.set(continuerr);
}
此外,如果end
变量不是易失性的,它可以缓存在线程中。
我们需要查看更多代码。 (或至少编译代码。)因为此代码按预期工作:
import java.util.concurrent.*;
public class MyClass {
static Producer p;
static Consumer c;
public static void main(String[] args) {
BlockingQueue q = new LinkedBlockingQueue();
p = new Producer();
c = new Consumer();
Thread t = new Thread(p);
t.start();
new Thread(c).start();
while (true) {
if (!p.getContinuer()) {
c.setContinuer(false);
break;
}
}
System.out.println("finish all");
}
}
class Producer implements Runnable {
private boolean end = true;
private BlockingQueue queue;
private AtomicBoolean continuer = new AtomicBoolean(true);
public boolean getContinuer() {
return continuer.get();
}
@Override
public void run() {
while (true) {
// open socket
// read data from socket
if (end) {
System.out.println("Shutting down Producer");
continuer.getAndSet(false);
break;
}
}
}
}
class Consumer implements Runnable {
private BlockingQueue queue;
private static AtomicBoolean continuer = new AtomicBoolean(true);
public void setContinuer(Boolean continuerr) {
continuer = new AtomicBoolean(continuerr);
}
public Boolean getContinuer() {
return continuer.get();
}
@Override
public void run() {
while (getContinuer()) {
// Do some work
}
System.out.println("shut down Consumer");
}
}
打印
Shutting down Producer
finish all
shut down Consumer
关于您的修改:
我改变了我的代码,显然消费者在尝试从BlockingQueue读取数据时被阻止(等待)(请参阅消费者类中的consume(queue.take()); < / p>
您应该在c.setContinuer(false);
做consumerThread.interrupt()
之后。在read
方法中被阻塞的消费者线程将抛出InterruptedException(您可以忽略它),然后退出循环并正常终止。
答案 1 :(得分:0)
就像aioobe说的那样,每次设置它时都会创建一个新的布尔对象。那很糟糕。
更糟糕的是,您有生产者和消费者的离散连续变量。因此,如果将Producer的布尔值设置为false,为什么Consumer会受到影响?你的意思是说Consumer.getAndSet(false)
吗?代码似乎有点复杂。
答案 2 :(得分:0)
您是否测试了
if (!p.getContinuer())
被采取?生产者的getContinuer未在您的示例中定义。 我会在
之后重新插入一个调试语句c.setContinuer(false);
获取c.getContinuer()
的值编辑:您应该为生产者和消费者使用一个Atomicboolean,正如其他答案所暗示的那样。