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(我也更改了打印)。正如你在我的代码中看到的,我已经在使用原子布尔。