2012-06-21 34 views
5

Điều gì xảy ra trong mã sau? Đồng bộ hóa có hoạt động không? Đây là một câu hỏi phỏng vấn.Điều gì sẽ xảy ra nếu biến đồng bộ được gán lại trong java?

class T 
{ 
    public static void main(String args[]) 
    { 
     Object myObject = new Object(); 
     synchronized (myObject) 
     { 
      myObject = new Object(); 
     } // end sync 
    } 
} 
+4

khối được đồng bộ hóa của bạn ở trong chính và không nằm trong vòng lặp, khối này sẽ chỉ được chạy một lần. Không có điểm nào trong việc đồng bộ hóa ở đây (trừ khi bạn gọi đó là chính từ một chính khác, điều này thật lạ). – assylias

Trả lời

4

Mỗi khi bạn nhập khối đã đồng bộ hóa, bạn đồng bộ hóa trên một đối tượng khác. Hầu hết thời gian này sẽ không làm bất cứ điều gì ngoại trừ nhầm lẫn bạn, nhưng có một cơ hội nhỏ mà hai chủ đề sẽ thấy cùng một đối tượng và chờ đợi.

Vì lý do này, bất kỳ trình phân tích mã nào sẽ cảnh báo nếu bạn đang đồng bộ hóa trên một trường không phải là final.

1

Nó vẫn phát hành màn hình tương tự mà đã được mua lại, nhưng bất kỳ mã khác cũng khóa sử dụng myObject (bất khả thi ở đây vì nó là một biến địa phương, làm cho đồng bộ về cơ bản vô nghĩa) sẽ bắt đầu sử dụng các đối tượng mới.

Đừng quên đồng bộ hóa được áp dụng cho đối tượng (hoặc đúng hơn là màn hình được liên kết với đối tượng) - không phải biến. Màn hình được mua/giải phóng chỉ phụ thuộc vào giá trị của biểu thức khi đạt được bắt đầu của khối được đồng bộ hóa. Biểu thức là không phải được đánh giá lại ở cuối khối được đồng bộ hóa.

0

Không, nó không hoạt động. Bất cứ khi nào một chuỗi mới xuất hiện, một myObject mới được tạo. Đặc biệt bây giờ là myObject là một biến địa phương!

Nó sẽ không hoạt động ngay cả khi myObject là thành viên của lớp vì bạn sẽ thay đổi đối tượng bạn đang khóa. Xem câu hỏi về synchronization of non-final field để được giải thích dài hơn.

0

tôi không thấy lý do đằng sau mã này vì đối tượng không được chia sẻ bởi bất kỳ chủ đề nào. Việc loại bỏ khối đồng bộ sẽ không ảnh hưởng đến kết quả thực sự trong mọi trường hợp. Nó sẽ chỉ làm cho mã của bạn chạy nhanh hơn

0

Bạn cần có khóa myObject trước, nếu khóa này bị khóa, bạn phải chờ cho đến khi khóa được giải phóng.

Đồng bộ hóa yêu cầu môi trường nhiều luồng.Nhưng mã của bạn dường như không liên quan gì đến việc đồng thời.Vì vậy, tôi rất tiếc phải thông báo với bạn rằng KHÔNG có sự cố nào xảy ra.

0

Chạy mã và phân tích kết quả.

public class Test { 
    static Foo o = new Foo(0); 
    static class Foo { 
     private int i = 0; 
     Foo(int i) { 
      this.i = i; 
     } 
     public void addOnce() { 
      this.i++; 
     } 
     public String toString() { 
      return String.valueOf(i); 
     } 
    } 
    public static void main(String args[]) { 
     test1(); 
     try {Thread.sleep(10000);} catch (Exception e) {} 
     test2(); 
    } 
    public static void test1() { 
     Runnable r = new Runnable() { 
      public void run() { 
       synchronized (o) { 
        System.out.println("1------>"+o); 
        o = new Foo(1); 
        try {Thread.sleep(3000);} catch (Exception e) {} 
        System.out.println("1------>"+o); 
       } 
      } 
     }; 
     new Thread(r).start(); 
     new Thread(r).start(); 
    } 
    public static void test2() { 
     Runnable r = new Runnable() { 
      public void run() { 
       synchronized (o) { 
        System.out.println("2------>"+o); 
        o.addOnce(); 
        try {Thread.sleep(3000);} catch (Exception e) {} 
        System.out.println("2------>"+o); 
       } 
      } 
     }; 
     new Thread(r).start(); 
     new Thread(r).start(); 
    } 
} 
Các vấn đề liên quan