📜  Java的对象级锁

📅  最后修改于: 2022-05-13 01:55:18.422000             🧑  作者: Mango

Java的对象级锁

Java中的每个对象都有一个唯一的锁。每当我们使用同步关键字时,只有锁的概念才会出现。如果一个线程想要在给定的对象上执行同步方法。首先,它必须获得该对象的锁。一旦线程获得锁,就可以在该对象上执行任何同步方法。一旦方法执行完成,线程就会自动释放锁。内部获取和释放锁由JVM负责,程序员不负责这些活动

当我们想要同步非静态方法或非静态代码块时,对象级锁是一种机制,以便只有一个线程能够在类的给定实例上执行代码块。

如果一个线程想要在给定的对象上执行同步方法。首先,它必须获得该对象的锁。一旦线程获得锁,就可以在该对象上执行任何同步方法。一旦方法执行完成,线程就会自动释放锁。内部获取和释放锁由 JVM 负责,程序员不负责这些活动。

方法:我们可以通过不同的方式在线程中锁定对象,如下所示:

方法一:



public class GeekClass
{
    public synchronized void GeekMethod(){}
}

方法二:

public class GeekClass
{
    public void GeekMethod(){
        synchronized (this)
        {
            // other thread safe code
        }
    }
}

方法三:

public class DemoClass
{
    private final Object lock = new Object();
    public void demoMethod(){
        synchronized (lock)
        {
            // other thread safe code
        }
    }
}

例子:

Java
// Java program to illustrate
// Object lock concept
 
// Class
// Extending Runnable interface
class Geek implements Runnable {
 
    // Method of this class
    public void run() { Lock(); }
 
    // Synchronization of non-static methods
    // (object lock) as different synchronized
    // non-static methods are called in both threads
 
    // Then both threads need to acquire the object lock
    // After one is acquired, the other thread must wait
    // for one thread to finish the executing
    // before the other thread starts to execute.
    public void Lock()
    {
        System.out.println(
            Thread.currentThread().getName());
        synchronized (this)
        {
            System.out.println(
                "in block "
                + Thread.currentThread().getName());
            System.out.println(
                "in block "
                + Thread.currentThread().getName()
                + " end");
        }
    }
 
    // Main driver method
    public static void main(String[] args)
    {
        // Creating an object of above class
        // in the main() method
        Geek g = new Geek();
 
        // Sharing the same object across two Threads
 
        // Here, t1 takes g
        Thread t1 = new Thread(g);
       
        // Here, t2 takes g
        Thread t2 = new Thread(g);
 
        // Creating another object of above class
        Geek g1 = new Geek();
 
        // Here, t3 takes g1
        Thread t3 = new Thread(g1);
 
        // setname() method is used to change
        // name of the thread
        t1.setName("t1");
        t2.setName("t2");
        t3.setName("t3");
 
        // start() method beginning the execution of threads
        // as JVM calls the run() method of thread
        t1.start();
        t2.start();
        t3.start();
    }
}



输出
t1
t3
t2
in block t1
in block t3
in block t1 end
in block t2
in block t2 end
in block t3 end