java - 通过两个不同的线程设置和访问变量

标签 java multithreading

我有两个线程,一个设置类的变量,另一个通过 get 方法访问该变量。

public class Parent {
    private int value = -1

    public int getValue()
      return this.value;
    }

    public void setValue(int value){
      this.value = value;
    }

    private class UpdatingVaribale extends Thread {

    public void run() {
      while (!Thread.currentThread().isInterrupted()) {
        try {
            setValue(2);
            Thread.currentThread().interrupt();
        }
      } 
    }
}

private class GettingVaribale extends Thread {

    public void run() {
      while (getValue == -1) {
        try{
            System.out.println(getValue);
            Thread.sleep(500);
         } catch (InterruptedException e) {
         }
       }
       System.out.println(getValue); 
    }
}

问题在于第二个线程中的while循环的条件始终为trueSystem.out.println(getValue) 始终打印 -1。我想知道为什么第二个线程没有获得 value 的新值,即 2。我认为synchronized在这里并不重要,因为一个线程正在设置变量,而另一个线程只是访问该变量。

最佳答案

这里有一些解决方案:

  1. 使用标准 Java 类 AtomicInteger 以多线程安全的方式存储您的值。实际上这是最好、最快的方法。
  2. synchronized 关键字添加到您的 getValuesetValue 方法
  3. volatile java 关键字添加到 i 字段定义

问题的根源是 i 变量值实际上在不同线程中看起来不同,原因是 CPU 速度和内存优化,并且您必须以某种方式指定 JVM 不要进行此优化 - 相反 -使最新的 i 值在所有线程中可见。

更新测试代码

public class SyncProblem {

    public static void main(String[] args) {
        Parent parent = new Parent();
        new Thread(parent.new GettingVaribale()).start();
        new Thread(parent.new UpdatingVaribale()).start();
    }
}

class Parent {
    private volatile int value = -1;

    public int getValue() {
        return this.value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    class UpdatingVaribale implements Runnable {
        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                setValue(2);
                Thread.currentThread().interrupt();
            }
        }
    }

    class GettingVaribale implements Runnable {
        @Override
        public void run() {
            while (getValue() == -1) {
                try {
                    System.out.println(getValue());
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                }
            }
            System.out.println(getValue());
        }
    }
}

关于java - 通过两个不同的线程设置和访问变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39669670/

相关文章:

java - 显示所有小于输入的素数的多线程程序

Java平均误差

c# - 当异步代码试图在一个已经在执行的线程上恢复时会发生什么?

android - 无法创建线程中的 WebView

c# - 当 ThreadStart 例程返回时,线程是否会自动停止?

c++ - 安全段错误?

java - 如何使用 android (PHP) 连接 MySQL 数据库?

java - 这个骑士之旅的算法如何修复?

java - 在没有互联网连接的网络中生产环境中通过 JNLP 应用程序启动缓慢

java - 设置 LDAP SecurityPrincipal 值