2010-07-29 21 views
11

Khi chúng ta nói về khóa nội tại, chúng ta đề cập đến đối tượng mà chúng ta yêu cầu khóa hoặc cho phương pháp đồng bộ?thread nội tại khóa

Khóa ở trên đối tượng hoặc trên phương pháp đồng bộ hóa của nó?

Tôi đang bối rối!

Trả lời

4

phương pháp đồng bộ khóa phương pháp trên đối tượng

synchronized void methodA() { 
    ....  
} 

là bằng cách nào đó tương đương với

void methodA() { 
    synchronized (this) { 
     .... 
    } 
} 
+0

Mọi đối tượng đều có khóa nội tại. Hai câu lệnh này là tương đương vì cả hai đều đồng bộ hóa trên khóa nội tại của đối tượng chứa phương thứcA(). – Brandon

+0

Giải thích các câu lệnh Đồng bộ hóa cho một người không hiểu các Phương thức đồng bộ hóa không phải là một ý tưởng hay. Điều này chỉ làm tôi bối rối hơn nữa. –

15

khóa Intrinsic đang trên đối tượng:

class A 
{ 
    public synchronized void method1(){...} 
    public synchronized void method2(){...} 
} 

Nếu thread A là trong method1 sau đó threadB không thể nhập method2.

+1

Tôi muốn, Stackoverflow cho phép tôi +10 cho dòng cuối cùng của bạn. :) – UnKnown

1

Khóa là một phần của đối tượng. Mỗi đối tượng có một và nó có thể bị khoá theo hai cách:

  1. Sử dụng synchronized sửa đổi trên một phương pháp thể hiện của các lớp để khóa các đối tượng liên quan đến
  2. Sử dụng một khối synchronized(object) {}

Tương tự như vậy, bạn có thể khóa Lớp đối tượng thay vì chính Đối tượng (đề cập riêng biệt để hiểu công cụ sửa đổi synchronized với phương pháp static):

  1. Sử dụng synchronized sửa đổi trên một phương pháp tĩnh của lớp để khóa Lớp
  2. Sử dụng một khối synchronized(clazz) {} nơi clazz là Lớp Object
0

Lock đang bật đối tượng. Trong Java mỗi đối tượng là một monitor

9

Trong Java, một khóa bên trong được ngụ ý bởi mỗi lần sử dụng từ khóa synchronized

Mỗi sử dụng từ khóa synchronized được kết hợp với một trong hai loại khóa nội tại:

một "khóa dụ", gắn liền với một đối tượng duy nhất

một "tĩnh khóa", gắn liền với một lớp

Nếu một phương pháp được khai báo là đồng bộ, sau đó nó sẽ có được một trong hai khóa dụ hoặc khóa tĩnh khi nó được gọi, theo cho dù đó là một phương thức thể hiện hay một phương thức tĩnh.

Hai loại khóa có hành vi tương tự nhau, nhưng hoàn toàn độc lập với nhau.

Lấy khóa thể hiện chỉ chặn các chủ đề khác yêu cầu phương thức thể hiện được đồng bộ hóa; nó không chặn các luồng khác yêu cầu một phương thức không đồng bộ hóa, cũng không chặn chúng khỏi việc gọi một phương thức đồng bộ hóa tĩnh.

Tương tự, việc mua khóa tĩnh chỉ chặn các luồng khác yêu cầu phương thức đồng bộ hóa tĩnh; nó không chặn các luồng khác khỏi việc gọi ra một phương thức không đồng bộ, cũng không chặn chúng khỏi việc gọi một phương thức thể hiện được đồng bộ hóa.

Bên ngoài tiêu đề phương pháp, đồng bộ hóa (điều này) có được khóa thể hiện.

Các khóa tĩnh có thể được mua bên ngoài của một tiêu đề phương pháp trong hai cách:

đồng bộ (Blah.class), sử dụng các lớp đen

đồng bộ (this.getClass()), nếu một đối tượng có sẵn

0
private int count = 0; 
public synchronized void countFunc(){ 
     count++; 
    } 
Thread t1 = new Thread(new Runnable(){ 
      public void run(){ 
      for(int i=0;i<1000;i++){ 
       countFunc(); 
       }}}); 
     Thread t2 = new Thread(new Runnable(){ 
      public void run(){ 
      for(int i=0;i<1000;i++){ 
       countFunc(); 
      }}}); 

Trong ví dụ trên, tôi có 2 chủ đề cố gắng tăng giá trị đếm. Và để ngăn chặn luồng xen kẽ, tôi đang cố gắng lấy một khóa nội tại bằng cách sử dụng đồng bộ hóa từ khóa.

cách thuyết phục, Trong ví dụ này, khóa phương pháp khối countFunc với đồng bộ từ khóa và khóatrên các đếm biến. Hy vọng điều này sẽ giúp

0

Khóa trên Object.

Có một cái nhìn tại trang hướng dẫn java trên intrinsic locks

Mỗi đối tượng có một khóa bên trong liên kết với nó. Theo quy ước, một luồng cần truy cập độc quyền và nhất quán vào các trường của đối tượng phải lấy khóa nội tại của đối tượng trước khi truy cập chúng, và sau đó giải phóng khóa nội tại khi nó được thực hiện với chúng. Một sợi dây được cho là sở hữu khóa bên trong giữa thời gian nó có khóa và mở khóa.

Miễn là một chủ sở hữu có khóa nội tại, không có chuỗi nào khác có thể có cùng khóa. Các chủ đề khác sẽ chặn khi nó cố gắng để có được khóa.

Hai cách sử dụng ổ khóa bên trong:

  1. phương pháp đồng bộ:

    Khi một thread gọi một phương pháp synchronized, nó tự động mua lại các nội khóa cho đối tượng của phương pháp đó và giải phóng nó khi phương thức trả về.

    ví dụ:

    public synchronized void incrementCounter(){ 
        ++counter; 
    } 
    
  2. báo cáo đồng bộ

    Không giống như các phương pháp synchronized, synchronized báo cáo phải ghi rõ đối tượng cung cấp các khóa nội

    public int getCounter(){ 
        synchronized(this){ 
         return counter; 
        } 
    } 
    

    Complete dụ:

    public class SynchronizedDemo{ 
    private int counter = 0; 
    
    public SynchronizedDemo(){ 
    
    } 
    public synchronized void incrementCounter(){ 
        ++counter; 
    } 
    public int getCounter(){ 
        synchronized(this){ 
         return counter; 
        } 
    } 
    public static void main(String[] args){ 
        SynchronizedDemo object = new SynchronizedDemo(); 
        for (int i=0; i < 5; i++){ 
         Thread t = new Thread(new SimpleRunnable(object)); 
         t.start(); 
        }   
    } 
    } 
    class SimpleRunnable implements Runnable{ 
    private SynchronizedDemo object; 
    
    public SimpleRunnable(SynchronizedDemo obj){ 
        this.object = obj; 
    } 
    public void run(){ 
        object.incrementCounter(); 
        System.out.println("Counter:"+object.getCounter()); 
    } 
    } 
    

Lưu ý: Ví dụ này chỉ được viết để giới thiệu các cách sử dụng khóa nội tại khác nhau. Sử dụng AtomicInteger cho biến số lượt truy cập là cách tiếp cận đúng cho loại trường hợp sử dụng này.

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