34

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

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

我想flag在主线程和帮助线程之间共享这是我创建的两个不同的 Java 类。有什么办法吗?谢谢!

4

7 回答 7

38

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

有关更多信息,请参阅本文

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

volatile并注意使用与更复杂的共享状态方式的优缺点。

于 2012-11-27T10:41:55.917 回答
19

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

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();
    }
  }
}
于 2012-11-27T11:14:41.117 回答
7

使用static不会帮助你的情况。

synchronize当变量被另一个线程使用时,Using会锁定一个变量。

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

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

于 2018-10-15T08:47:10.680 回答
6

要使其在 和 的实例之间可见T1T2您可以使两个类包含对包含变量的对象的引用。

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

  • 制作变量volatile
  • 把它变成一个AtomicBoolean
  • 围绕使用它的代码使用全面同步。
于 2012-11-27T10:43:33.250 回答
5
  1. 将其设为静态可以解决此问题。
  2. 引用其他线程中的主线程并使该变量可见
于 2012-11-27T10:42:46.150 回答
2

您可以使用锁定变量“a”和“b”并同步它们以以相反的顺序锁定“关键部分”。例如。通知“a”然后锁定“b”,“PRINT”,通知“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 
于 2017-12-30T16:08:49.140 回答
0
于 2021-01-05T06:49:22.600 回答