首页 > 解决方案 > 两个线程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 变量,但输出没有改变。我在这里错过了什么?请帮忙...

标签: javamultithreadingvariablesstaticruntime

解决方案


您可以使用 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();
            }
        }
    }
}

推荐阅读