Java 中的对象级和类级锁
原文:https://www . geesforgeks . org/object-level-class-level-lock-Java/
同步:
同步是仅用于方法和块的修改器。在同步修饰符的帮助下,我们可以限制共享资源只能被一个线程访问。当两个或多个线程需要访问共享资源时,会有一些数据丢失,即数据不一致。我们可以在多个线程之间实现数据一致性的过程称为同步。
为什么需要同步?
让我们假设您有两个线程正在读取和写入同一个“资源”。假设有一个名为 geek 的变量,您希望一次只有一个线程可以访问该变量(原子方式)。但是如果没有 synchronized 关键字,线程 1 可能看不到线程 2 对 geek 所做的更改,或者更糟的是,可能只有一半的更改会导致数据不一致的问题。这不是你逻辑上所期望的。防止这些错误所需的工具是同步。
在同步中,线程上有两种锁:
- 对象级锁:Java 中的每个对象都有一个唯一的锁。每当我们使用同步关键字时,只有锁的概念会出现在图片中。如果一个线程想要在给定的对象上执行同步方法。首先,它必须锁定该对象。一旦线程获得了锁,那么它就被允许对该对象执行任何同步的方法。一旦方法执行完成,线程会自动释放锁。内部获取和释放锁由 JVM 负责,程序员不对这些活动负责。让我们看看下面的程序,了解对象级锁定:
Java 语言(一种计算机语言,尤用于创建网站)
// Java program to illustrate
// Object lock concept
class Geek implements Runnable {
public void run() { Lock(); }
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");
}
}
public static void main(String[] args)
{
Geek g = new Geek();
Thread t1 = new Thread(g);
Thread t2 = new Thread(g);
Geek g1 = new Geek();
Thread t3 = new Thread(g1);
t1.setName("t1");
t2.setName("t2");
t3.setName("t3");
t1.start();
t2.start();
t3.start();
}
}
Output
t1
t3
t2
in block t3
in block t1
in block t3 end
in block t1 end
in block t2
in block t2 end
- 类级锁:Java 中的每个类都有一个唯一的锁,这个锁只不过是类级锁。如果一个线程想要执行一个静态同步方法,那么这个线程需要一个类级锁。一旦线程获得了类级别的锁,那么它就被允许执行该类的任何静态同步方法。一旦方法执行完成,线程会自动释放锁。让我们看看下面的程序,以便更好地理解:
Java 语言(一种计算机语言,尤用于创建网站)
// Java program to illustrate class level lock
class Geek implements Runnable {
public void run() { Lock(); }
public void Lock()
{
System.out.println(
Thread.currentThread().getName());
synchronized (Geek.class)
{
System.out.println(
"in block "
+ Thread.currentThread().getName());
System.out.println(
"in block "
+ Thread.currentThread().getName()
+ " end");
}
}
public static void main(String[] args)
{
Geek g1 = new Geek();
Thread t1 = new Thread(g1);
Thread t2 = new Thread(g1);
Geek g2 = new Geek();
Thread t3 = new Thread(g2);
t1.setName("t1");
t2.setName("t2");
t3.setName("t3");
t1.start();
t2.start();
t3.start();
}
}
Output
t1
t2
t3
in block t1
in block t1 end
in block t3
in block t3 end
in block t2
in block t2 end
参考:https://docs . Oracle . com/javase/tutorial/essential/concurrency/sync . html
本文由比沙尔·库马尔·杜贝供稿。如果你喜欢 GeeksforGeeks 并想投稿,你也可以使用contribute.geeksforgeeks.org写一篇文章或者把你的文章邮寄到 contribute@geeksforgeeks.org。看到你的文章出现在极客博客主页上,帮助其他极客。
如果你发现任何不正确的地方,或者你想分享更多关于上面讨论的话题的信息,请写评论。
版权属于:月萌API www.moonapi.com,转载请注明出处