在多个不同线程之间共享变量

问题描述 投票:15回答:6

我想在多个线程之间共享一个变量,如下所示:

boolean flag = true;
T1 main = new T1();
T2 help = new T2();
main.start();
help.start();

我想在main和help线程之间共享flag,这是我创建的两个不同的Java类。有办法做到这一点吗?谢谢!

java multithreading synchronization shared
6个回答
28
投票

T1T2都可以引用包含此变量的类。 然后,您可以将此变量设置为volatile,这意味着 在两个线程中都可以立即看到对该变量的更改。

有关更多信息,请参阅this article

易失性变量共享同步但不具有原子性特征的可见性特征。这意味着线程将自动查看volatile变量的最新值。它们可用于提供线程安全性,但仅限于非常有限的一组情况:不在多个变量之间或变量的当前值与其未来值之间施加约束的情况。

并注意使用volatile与更复杂的共享状态手段的利弊。


14
投票

除了其他建议之外 - 您还可以将标志包装在控件类中,并在父类中创建它的最终实例:

public class Test {
  class Control {
    public volatile boolean flag = false;
  }
  final Control control = new Control();

  class T1 implements Runnable {
    @Override
    public void run() {
      while ( !control.flag ) {

      }
    }
  }

  class T2 implements Runnable {
    @Override
    public void run() {
      while ( !control.flag ) {

      }
    }
  }

  private void test() {
    T1 main = new T1();
    T2 help = new T2();

    new Thread(main).start();
    new Thread(help).start();
  }

  public static void main(String[] args) throws InterruptedException {
    try {
      Test test = new Test();
      test.test();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

4
投票
  1. 使其静态可以解决这个问题。
  2. 引用其他线程中的主线程并使该变量可见

4
投票

为了使它在T1T2的实例之间可见,您可以使这两个类包含对包含该变量的对象的引用。

如果要在线程运行时修改变量,则需要考虑同步。最佳方法取决于您的确切要求,但主要选项如下:

  • 使变量volatile;
  • 把它变成AtomicBoolean;
  • 在使用它的代码周围使用全面的同步。

4
投票

使用static对你的情况没有帮助。

使用synchronize在另一个线程使用时锁定变量。

您应该使用volatile关键字来保持变量在所有线程中更新。

使用volatile是使类线程安全的另一种方式(如同步,原子包装)。线程安全意味着多个线程可以同时使用方法或类实例而不会出现任何问题。


0
投票

您可以使用锁定变量“a”和“b”并同步它们以反向顺序锁定“临界区”。例如。通知“a”然后锁定“b”,“打印”,通知“b”然后锁定“a”。

请参考以下代码: -

public class EvenOdd {

static int a = 0;

public static void main(String[] args) {

    EvenOdd eo = new EvenOdd();

    A aobj = eo.new A();
    B bobj = eo.new B();

    aobj.a = Lock.lock1;
    aobj.b = Lock.lock2;

    bobj.a = Lock.lock2;
    bobj.b = Lock.lock1;

    Thread t1 = new Thread(aobj);
    Thread t2 = new Thread(bobj);

    t1.start();
    t2.start();

}

static class Lock {
    final static Object lock1 = new Object();
    final static Object lock2 = new Object();
}

class A implements Runnable {

    Object a;
    Object b;

    public void run() {
        while (EvenOdd.a < 10) {
            try {
                System.out.println(++EvenOdd.a + " A ");
                synchronized (a) {
                    a.notify();
                }
                synchronized (b) {
                    b.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

class B implements Runnable {

    Object a;
    Object b;

    public void run() {
        while (EvenOdd.a < 10) {

            try {
                synchronized (b) {
                    b.wait();
                    System.out.println(++EvenOdd.a + " B ");
                }
                synchronized (a) {
                    a.notify();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

}

输出: - 1 A 2 B 3 A 4 B 5 A 6 B 7 A 8 B 9 A 10 B

© www.soinside.com 2019 - 2024. All rights reserved.