Java 在线程之间共享一个变量?
我有这样一个场景:Java 在线程之间共享一个变量?,java,multithreading,synchronization,locking,Java,Multithreading,Synchronization,Locking,我有这样一个场景: 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);
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”没有更新
我也看到了和帖子,我试过了,但没什么变化
我有什么问题
编辑:我更改了代码,显然消费者在尝试从中读取数据时被阻止了()(请参阅consumer类中的consume(queue.take())。好吧
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读取数据时被阻止(等待)(请参阅consumer类中的consume(queue.take())。
你应该在你的
c.setContinuer(false)之后代码>执行用户读取.interrupt()
。在read
方法中被阻塞的使用者线程将抛出InterruptedException(您可以忽略),然后退出循环并优雅地终止。就像aioobe所说的,每次设置它时,您都在创建一个新的布尔对象。那太糟糕了
更糟糕的是,生产者和消费者都有离散的连续变量。因此,如果将生产者的布尔值设置为false,为什么消费者会受到影响?你的意思是说Consumer.getAndSet(false)
?代码似乎有点复杂。您是否测试过
if (!p.getContinuer())
有人吗?示例中未定义生产者的getContinuer。
我建议在之后插入调试语句
c.setContinuer(false);
获取c.getContinuer()的值
编辑:你应该像其他答案所建议的那样为生产者和消费者使用一个Atomicboolean。@aioobe-这将是一个问题:)不,我的代码是编译的(这只是我代码的一个示例,所以可能有一些错误)。对不起,我发现了问题(我更改了帖子)。谢谢你的答案,但这不起作用。不,end没有被缓存,因为你可以看到线程在MyClass和Producer中完成了它的工作。对不起,但是我发现了问题(我更改了帖子)。我在MyClass中有一行“c.setContinuer(false);”对不起,我忘了它(我更改了代码)。c、 getContinuer()包含false(我也更改了打印)。正如你在我的代码中看到的,我已经在使用原子布尔。