2011-02-03 39 views
37

tôi có mã này trong Java:Nested đồng bộ từ khóa

public void doSomeThing() { 
     synchronized (this) { 
      doSomeThingElse(); 
     } 
    } 
    public void doSomeThingElse() { 
     synchronized (this) { 
      // do something else 
     } 
    } 

Can khối mã này? Ý tôi là, mã này có thể đợi không?

Trả lời

47

Khi java documentation describes cho reentrant khóa:

a thread có thể có được một khóa mà nó đã sở hữu

Khối đồng bộ thứ hai là sử dụng khóa giống nhau và do đó sẽ luôn luôn được có thể sử dụng được vì khóa đã được nuôi dưỡng trong phương pháp bên ngoài.

Không, sẽ không có bế tắc.

1

Khóa đã bị xâu chuỗi bởi phương thức thực thi doSomething, do đó luồng này có thể thực thi phương thức doSomethingElse.

Bạn cần hai đối tượng khóa để tạo tình huống bế tắc. Trong trường hợp của bạn, chỉ có một, do đó không thể tạo ra bế tắc.

+0

Bạn có nghĩa là mã [// làm điều gì khác] có thể chạy chính xác không? –

+0

Vâng, nó sẽ chạy đúng .. nếu không, bạn nên đăng tất cả các mã cần thiết. –

+0

Anh ấy có nghĩa là luồng đã có khóa bắt buộc cho phương thức bảo mật để nó không tự khóa. – kasten

3

Trong khối được đồng bộ hóa, bạn có thể khôi phục lại khóa mà bạn đã sở hữu. Nhà cung cấp khóa (này) sẽ được mua bởi chuỗi đầu tiên để nhập doSomething(). Sau đó, trong phương thức doSomethingElse() nó sẽ tái hấp thu nó.

Lý do để làm điều này? Cũng không có gì để nói rằng không có một số thread khác nhập doSomethingElse từ nơi khác. Điều này sẽ ngăn chặn bất kỳ mã nào thực hiện khối trong doSomething() cho đến khi luồng trong doSomethingElse() đã phát hành "this".

Chỉnh sửa BTW nó có thể chặn khóa học ... và nó sẽ chặn bất kỳ chuỗi nào không sở hữu đối tượng đồng bộ hóa thực thi. Tuy nhiên nó sẽ không (như được đăng) bế tắc.

0

Việc sử dụng đồng bộ trong cả hai trường hợp this vì vậy nếu khối đồng bộ trong doSomeThing chạy, bạn đã có sẵn khóa để có thể thực hiện phương thức doSomeThingElse.

Nếu mã của bạn là đơn giản như vậy, nó tương đương với:

public synchronized void doSomeThing() { 
    doSomeThingElse(); 
} 
public synchronized void doSomeThingElse() { 
    // do something else 
} 
0

Bạn đã đưa ra những khóa màn hình trong lần đầu tiên đồng bộ. Bạn nên luôn luôn đảm bảo rằng thiết kế đồng thời không làm cho tác động hiệu suất lớn.

Một cách để đảm bảo điều này là bằng cách đồng bộ hóa chỉ các báo cáo/mã được yêu cầu.

Giả sử mã của bạn sẽ trông giống như thế này.

public void doSomeThing() 
{ 
    synchronized (this) 
    {    
    synchronized (this) 
    {    
     // do something else   
    }   
    }  
} 

Trong khi đây là những gì được yêu cầu

public void doSomeThing() 
    { 
     doSomeThingElse();  
    } 
public void doSomeThingElse() 
{ 
synchronized (this) 
     {    
      // do something else   
     } 
} 
7

Nếu một thread sở hữu khóa trên this, nó sẽ đi vào synchronized phương pháp khác/block như dao nóng trong bơ.

+7

Nó sẽ chia đối tượng của tôi? Đó là phép ẩn dụ… – Kissaki

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