Ну,
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 (см. Потребление (queue.take ()); в классе потребителя).
Вы должны после вашего c.setContinuer(false);
сделать consumerThread.interrupt()
.Поток-потребитель, заблокированный в методе read
, сгенерирует исключение InterruptedException (которое можно игнорировать), а затем выйдет из цикла и завершит работу корректно.