简体   繁体   English

线程内在锁

[英]thread intrinsic lock

When we talk about intrinsic lock we refer to the object for which we ask the lock or for the synchronized method? 当我们谈论内在锁时,我们引用了我们要求锁或同步方法的对象?

The lock is on the object or on it's sync method? 锁定在对象上还是在同步方法上?

I'm confused! 我糊涂了!

Intrinsic locks are on the object: 内部锁在对象上:

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

If thread A is in method1 then threadB cannot enter method2. 如果线程A在method1中,则threadB无法进入method2。

In Java, an intrinsic lock is implied by each use of the synchronized keyword 在Java中,每次使用synchronized关键字都会隐含内在锁定

Each use of the synchronized keyword is associated with one of the two types of intrinsic lock: synchronized关键字的每次使用都与两种类型的内部锁定之一相关联:

an "instance lock", attached to a single object “实例锁”,附加到单个对象

a "static lock", attached to a class 一个“静态锁”,附在一个类上

If a method is declared as synchronized, then it will acquire either the instance lock or the static lock when it is invoked, according to whether it is an instance method or a static method. 如果一个方法被声明为synchronized,那么它将在调用时获取实例锁或静态锁,具体取决于它是实例方法还是静态方法。

The two types of lock have similar behaviour, but are completely independent of each other. 这两种类型的锁具有相似的行为,但完全相互独立。

Acquiring the instance lock only blocks other threads from invoking a synchronized instance method; 获取实例锁只会阻止其他线程调用同步实例方法; it does not block other threads from invoking an un-synchronized method, nor does it block them from invoking a static synchronized method. 它不会阻止其他线程调用非同步方法,也不会阻止它们调用静态同步方法。

Similarly, acquiring the static lock only blocks other threads from invoking a static synchronized method; 类似地,获取静态锁仅阻止其他线程调用静态同步方法; it does not block other threads from invoking an un-synchronized method, nor does it block them from invoking a synchronized instance method. 它不会阻止其他线程调用非同步方法,也不会阻止它们调用同步实例方法。

Outside of a method header, synchronized(this) acquires the instance lock. 在方法头之外,synchronized(this)获取实例锁。

The static lock can be acquired outside of a method header in two ways: 静态锁可以通过两种方式在方法头之外获取:

synchronized(Blah.class), using the class literal synchronized(Blah.class),使用类文字

synchronized(this.getClass()), if an object is available synchronized(this.getClass()),如果对象可用

Synchronized methods locks the method on the object 同步方法将方法锁定在对象上

synchronized void methodA () {
    ....    
}

is somehow equivalent to 在某种程度上相当于

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

The lock is part of the Object. 锁是Object的一部分。 Every Object has one and it may be locked in two ways: 每个对象都有一个,它可以通过两种方式锁定:

  1. Using the synchronized modifier on an instance method of the Class to lock the associated object 在Class的实例方法上使用synchronized修饰符来锁定关联的对象
  2. Using a synchronized(object) {} block 使用synchronized(object) {}

Similarly, you can lock the Class of an Object instead of the Object itself (bares mentioning separately to understand the synchronized modifier with a static method): 类似地,您可以锁定Object的Class而不是Object本身(分别提到使用static方法来理解synchronized修饰符):

  1. Using the synchronized modifier on a static method of the Class to lock the Class 在Class的静态方法上使用synchronized修饰符来锁定Class
  2. Using a synchronized(clazz) {} block where clazz is the Class of the Object 使用synchronized(clazz) {}块,其中clazz是Object的Class

Lock is on the object. 锁定在对象上。 In Java every object is a monitor 在Java中,每个对象都是一个监视器

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

In the above example, I have 2 threads trying to increment the value of count. 在上面的例子中,我有2个线程试图增加count的值。 And to prevent thread interleaving I am trying to grab an intrinsic lock by the use of synchronized keyword. 并且为了防止线程交错,我试图通过使用synchronized关键字来获取内部锁。

Conclusively, In this example, lock is the method block countFunc with the synchronized keyword and lock is on the count variable. 决定性,在本例中, 同步关键字方法块countFunc锁定 计数变量。 Hope this helps 希望这可以帮助

The lock is on Object. 锁在Object上。

Have a look at java tutorial page on intrinsic locks 看一下内部锁的 java教程页面

Every object has an intrinsic lock associated with it. 每个对象都有一个与之关联的内在锁。 By convention, a thread that needs exclusive and consistent access to an object's fields has to acquire the object's intrinsic lock before accessing them, and then release the intrinsic lock when it's done with them. 按照惯例,需要对对象字段进行独占和一致访问的线程必须在访问对象之前获取对象的内部锁,然后在完成它们时释放内部锁。 A thread is said to own the intrinsic lock between the time it has acquired the lock and released the lock. 据说一个线程在获得锁定和释放锁定之间拥有内在锁定。

As long as a thread owns an intrinsic lock, no other thread can acquire the same lock. 只要一个线程拥有一个内部锁,没有其他线程可以获得相同的锁。 The other thread will block when it attempts to acquire the lock. 另一个线程在尝试获取锁时将阻塞。

Two ways of using intrinsic locks: 两种使用内部锁的方法:

  1. Synchronized methods: 同步方法:

    When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that method's object and releases it when the method returns. 当线程调用synchronized方法时,它会自动获取该方法对象的内部锁 ,并在方法返回时释放它。

    eg 例如

     public synchronized void incrementCounter(){ ++counter; } 
  2. Synchronized statements 同步语句

    Unlike synchronized methods, synchronized statements must specify the object that provides the intrinsic lock synchronized方法不同, synchronized语句必须指定提供内部锁的对象

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

    Complete example: 完整的例子:

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

Note: This example is written only to showcase different ways of using intrinsic locks. 注意:编写此示例仅用于展示使用内部锁的不同方法。 Using AtomicInteger for counter variable is right approach for this type of use case. 对于这种用例,使用AtomicInteger作为计数器变量是正确的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM