Java 中的类级锁
Java 中的每个类都有一个唯一的锁,这个锁就是 类级锁 。如果一个线程想要执行一个静态同步方法,那么这个线程需要一个类级锁。类级锁防止多个线程在运行时进入该类的任何可用实例中的同步块。这意味着,如果在运行时一个类有 10 个实例,那么一次只有一个线程能够访问任何一个实例的一个方法或块。如果您想要保护静态数据,则使用它。
如果一个线程想要执行一个静态同步方法,那么这个线程需要一个类级锁。一旦线程获得了类级别的锁,那么它就被允许执行该类的任何静态同步方法。一旦方法执行完成,线程会自动释放锁。
方法:线程可以通过两种方法获取类级别的锁,即
- Use the synchronous static method.
- Adopt synchronous block.
方法 1: 使用同步静态方法
实现:我们有一个极客班。我们想用这个类的静态同步方法,线程一进入 synchronized 方法,线程就在类级别获取锁,其余线程等待获取类监视器锁。当线程从同步方法中退出时,它会留下一个锁。
public static synchronized int incrementCount()
{
}
示例
Java
// Java program to illustrate class level lock
// Main Class
// Implememnting the Runnable interface
class Geek implements Runnable {
// Method 1
// @Override
public void run() { Lock(); }
// Method 2
// Method is static
public static synchronized void Lock()
{
// Gwetting the name of current thread by using
// getName() method to get name of the thread and
// currentThread() to get the current thread
System.out.println(
Thread.currentThread().getName());
// class level lock
synchronized (Geek.class)
{
System.out.println(
"in block "
+ Thread.currentThread().getName());
System.out.println(
"in block "
+ Thread.currentThread().getName()
+ " end");
}
}
// Method 3
// Main driver method
public static void main(String[] args)
{
// Creating an object of above class
// in the main() method
Geek g1 = new Geek();
// Sharing the same object across two Threads
// Creating an object of thread class where
// t1 takes g1
Thread t1 = new Thread(g1);
// Creating an object of thread class where
// t2 takes g1
Thread t2 = new Thread(g1);
// Creating second object of above class
// in the main() method
Geek g2 = new Geek();
// Creating an object of thread class where
// t3 takes g2
Thread t3 = new Thread(g2);
// setName() method is used to set name to the
// thread
t1.setName("t1");
t2.setName("t2");
t3.setName("t3");
// start() method is used for initiating the current
// thread
t1.start();
t2.start();
t3.start();
}
}
输出
t1
in block t1
in block t1 end
t3
in block t3
in block t3 end
t2
in block t2
in block t2 end
输出解释:
线程 t1 进入静态同步方法,并持有 Geek 类的锁。因此,其余的线程等待线程 t1 释放极客类的锁,以便它可以进入静态同步方法。
方法二:采用同步阻断法
实现:我们有一个“极客”班。我们想创建一个同步块并传递类名。类作为参数告诉哪个类必须在类级别同步。一旦线程进入同步块,线程就获取类的锁,其余线程等待获取类监视器锁。当线程从同步块退出时,它将离开锁。
synchronized (Geek.class) {
//thread has acquired lock on Geek class
}
例
爪哇
// Java program to illustrate class level lock
// Main Class
// It is implementing the Runnable interface
class Geek implements Runnable {
// Method 1
// @Override
public void run()
{
// Acquire lock on .class reference
synchronized (Geek.class)
// ClassName is name of the class containing method.
{
{
System.out.println(
Thread.currentThread().getName());
System.out.println(
"in block "
+ Thread.currentThread().getName());
System.out.println(
"in block "
+ Thread.currentThread().getName()
+ " end");
}
}
// Method 2
// Main driver method
public static void main(String[] args)
{
// Creating an object of above class
// in the main() method
Geek g1 = new Geek();
// Creating an object of thread class i.e Thread
// 1 where t1 takes g1 object
Thread t1 = new Thread(g1);
// Here, creating Thread 2 where t2 takes g1
// object
Thread t2 = new Thread(g1);
// Creating another object of above class
// in the main() method
Geek g2 = new Geek();
// Now reating Thread 3 where t3 takes g2 object
Thread t3 = new Thread(g2);
// Ginving custom names to above 3 threads
// using the setName() method
t1.setName("t1");
t2.setName("t2");
t3.setName("t3");
// start() method is used to begin execution of
// threads
t1.start();
t2.start();
t3.start();
}
}
输出:
t1
in block t1
in block t1 end
t3
in block t3
in block t3 end
t2
in block t2
in block t2 end
输出解释:
线程 t1 进入同步块,并持有“极客”类的锁。因此,其余的线程等待线程 t1 释放“极客”类上的锁,以便它可以进入同步块。
版权属于:月萌API www.moonapi.com,转载请注明出处