2012-11-27 30 views
8

tôi muốn chia sẻ một biến giữa nhiều chủ đề như thế này:Chia sẻ một biến giữa nhiều chủ đề khác nhau

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

Tôi muốn chia sẻ flag giữa chính và giúp đỡ chủ đề mà đây là hai lớp Java khác nhau tôi đã tạo. Có cách nào để làm điều này không? Cảm ơn!

Trả lời

17

Cả hai T1T2 có thể tham chiếu đến một lớp có chứa biến này. Sau đó, bạn có thể biến biến này biến động và điều này có nghĩa là các thay đổi đối với biến đó được hiển thị một cách tự nhiên trong cả hai luồng.

Xem this article để biết thêm thông tin.

Biến dễ bay hơi chia sẻ các tính năng hiển thị của đồng bộ hóa, nhưng không có tính năng nguyên tử nào. Điều này có nghĩa là các chuỗi sẽ tự động xem các giá trị được cập nhật nhất cho các biến dễ bay hơi . Chúng có thể được sử dụng để cung cấp an toàn luồng, nhưng chỉ trong một nhóm trường hợp giới hạn rất : những trường hợp không áp đặt ràng buộc giữa nhiều biến hoặc giữa giá trị hiện tại của biến và giá trị trong tương lai.

và lưu ý ưu/khuyết điểm của việc sử dụng các phương tiện chia sẻ dễ bay hơi và phức tạp hơn.

+0

Cảm ơn bạn đã trả lời nhưng bạn sẽ như thế nào tham khảo "cờ" từ bên trong T1, ví dụ? Tôi đã thử một cái gì đó như ParentClass.flag (nơi ParentClass là lớp mà từ đó tôi bắt đầu "chính" và "trợ giúp") và nó dường như không hoạt động ... – user1031431

+0

Khởi tạo T1/T2 với tham chiếu đến lớp chứa của chúng và làm cho lá cờ trở thành thành viên của lớp đó? –

4
  1. Làm cho nó tĩnh có thể khắc phục vấn đề này.
  2. Liên quan đến các chủ đề chính trong chủ đề khác và làm cho rằng biến có thể nhìn thấy
3

Để làm cho nó rõ ràng giữa các trường hợp T1T2 bạn có thể làm cho hai lớp chứa một tham chiếu đến một đối tượng có chứa biến.

Nếu biến được sửa đổi khi chuỗi đang chạy, bạn cần xem xét đồng bộ hóa. Cách tiếp cận tốt nhất tùy thuộc vào yêu cầu chính xác của bạn, nhưng các tùy chọn chính như sau:

  • biến biến volatile;
  • biến nó thành AtomicBoolean;
  • sử dụng đồng bộ hóa toàn diện xung quanh mã sử dụng mã đó.
6

Ngoài những gợi ý khác - bạn cũng có thể quấn cờ trong một lớp học kiểm soát và thực hiện một ví dụ cuối cùng của nó trong lớp cha mẹ của bạn:

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(); 
    } 
    } 
} 
+0

Cảm ơn tất cả các bạn. OldCurmufgeon, đó là những gì tôi đang tìm kiếm;) – user1031431

0

Bạn có thể sử dụng các biến khóa "a" và "b" và đồng bộ hóa chúng để khóa "phần quan trọng" theo thứ tự ngược lại. Ví dụ. Thông báo "a" rồi Khóa "b", "IN", Thông báo "b" rồi Khóa "a".

Vui lòng tham khảo các mã dưới đây: -

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(); 
      } 

     } 
    } 
} 

}

OUTPUT: - 1 Một 2 B 3 Một 4 B 5 A 6 B 7 Một 8 B 9 A 10 B

Các vấn đề liên quan