学习了 使用队列一边读取数据,一边写入数据,但是“更常用的方式”还有个问题,如果多次调用,stop的值,会被改变,因此不能把stop变为全局的,要声明为内部的。
声明为内部对象,会有个问题,
Variable used in lambda expression should be final or effectively final
这个时候可以用AtomicBoolean: AtomicBoolean stop = new AtomicBoolean(false);
用对象的方式去处理,可以set和get
QueueStopInner
public class QueueStopInner {
/**
* 批量存入数据
*/
private static final int MAX_SIZE = 10;
public static void main(String args[]) {
new QueueStopInner().run();
try {
Thread.sleep(10_000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
final BlockingQueue<Long> queue = new LinkedBlockingQueue<>();
AtomicBoolean stop = new AtomicBoolean(false);
// 往队列里面赋值
Thread writer = new Thread(() -> {
Long num = NumberUtils.LONG_ONE;
while (true) {
try {
queue.put(num);
num++;
if(num >= 105){
stop.set(true);
break;
}
long time = (long) (Math.random() * 100);
// 延迟添加,用于展示效果
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
writer.start();
// 读取队列里面堵塞的数据
Thread reader = new Thread(() -> {
List<Long> data = new ArrayList<>(MAX_SIZE);
while (!stop.get() || !queue.isEmpty()) {
try {
data.add(queue.take());
} catch (Throwable e) {
e.printStackTrace();
}
if(data.size() >= MAX_SIZE){
System.out.println(data);
data.clear();
}
}
if(!data.isEmpty()){ // 任务结束了,但可能还有数据
System.out.println(data);
data.clear();
}
});
reader.start();
}
}
总结:
如果使用lambda 表达式,如果要改变变量的值,考虑使用Atomic的数据类型,用对象的方式去处理,可以set和get