java - 两个线程Java之间的静态值共享
问题描述
我有两个不同的子进程在两个不同的线程中运行两个不同的命令。第二个线程更新静态变量中的值,第一个线程获取并使用该值。
流程应该是这样的:线程 2 更新静态变量,线程 1 从静态变量中获取值,然后打印它。但是发生的流程是线程 1 首先从静态变量中获取值。在这种情况下,它有一个空值,然后 thread2 更新该值。
两个线程都并行运行,我正在使用 ExecutorService 类来执行此操作。我正在使用 Runtime 类来运行命令,并使用 while 循环在两个线程上连续读取 Stream 的输出。
线程 1 继续提供 (X,Y) 值,线程 2 仅在获得文本时才给出值。
我得到的输出:
(12, 123) null --> thread2 没有得到任何值,所以它不会更新,thread1 将从静态变量中获取 null
(123,334) null --> thread1 从静态变量中获取值并使用它,thread2然后将值 "Hello" 更新为静态变量
(134,654) "Hello" --> thread1 拾取 "Hello" 并使用它,thread2 然后将值 "World" 更新为静态变量
预期输出:
(12, 123) null --> thread2 没有得到任何值,所以它没有更新,thread1 将从静态变量中获取 null
(123,334) "Hello" --> thread2 将值 "Hello" 更新为静态变量,thread1 选择它起来并使用它
(134,654) "World" --> thread2 将值 "World" 更新为静态变量,thread1 拾取并使用它
我也使用了 volatile 变量,但输出没有改变。我在这里错过了什么?请帮忙...
解决方案
您可以使用 java.util.concurrent.Semaphore(从 Java 5 开始)来控制同时访问它们共有的变量的线程数。您使用允许的线程数(调用了 acquire())来实例化此类使用它们的共同点,如果你传递 0,这意味着它们都不能修改它。
public class Threaad extends Thread{
volatile static String string;
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(0);
Thread writer = new Write(semaphore);
writer.setName("writer");
Thread reader = new Read(semaphore);
reader.setName("reader");
ExecutorService service = Executors.newCachedThreadPool();
service.execute(writer);
service.execute(reader);
service.shutdown();
}
}
class Write extends Thread{
private Semaphore semaphore;
Write(Semaphore semaphore){
this.semaphore = semaphore;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
Threaad.string = String.valueOf(i);
semaphore.release();
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Read extends Thread{
private Semaphore semaphore;
Read(Semaphore semaphore){
this.semaphore = semaphore;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
semaphore.acquire();
System.out.println(Threaad.string);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
推荐阅读
- angular - 角度延迟加载:loadChildren 不同的行为
- python - 如何仅使用函数编写计算器?
- git - git log 错误“致命:不明确的参数'filename.sh':未知修订或路径不在工作树中”
- excel - 您可以使用 VBA 在 Excel 中的整个工作表上删除公式中的工作簿引用吗?
- node.js - 使用 mongodb an node js 中的 where cluse 搜索对象
- java - 根据歌曲 ID 编辑歌曲艺术家姓名和歌曲名称
- terraform - 通过云教程工作的变量问题
- apex-code - 向上 SOQL 在某些领域打嗝,但在其他领域没有
- python - ndarrays的条件过滤
- sql - 制作调用它的程序日志