java - 线程获得级别

标签 java multithreading synchronization synchronized

我不是很清楚

Java Thread acquires an object level lock when it enters into an instance synchronized java method and acquires a class level lock when it enters into static synchronized java method.

对象级锁和类级锁是什么意思?

例如:

 public class Counter{
      private static int count = 0;
      private int count2 = 0;

      public static synchronized int getCount(){
           return count;
      }
      public synchronized setCount(int count2){
           this.count2 = count2;
      }
 } 

这里的 getCount() 将锁定 Counter.class 对象,而 setCount() 将锁定当前对象 (this)。 this 指的是什么?这是否意味着当调用 getCount() 时,另一个线程无法访问 setCount(),因为整个类都被锁定了?

最佳答案

What does it mean When it says object level lock and class level lock ?

当您锁定 static 方法时,您将锁定 Class 对象本身,并且每个 ClassLoader 都有一个。在你的例子中,

public static synchronized int getCount(){

这是锁定在 Counter.class 对象上,与以下内容相同:

public static int getCount() {
    synchronized (Counter.class) {
    }

如果您锁定的是不是 static 的方法,那么您锁定的是拥有该方法的对象的实例。在你的例子中:

public synchronized void setCount(int count){

这与锁定特定的 Counter 实例相同,等效于:

public void setCount(int count){
    synchronized (this) {
       ...

因此,如果您有 2 个 Counter 对象,counter1counter2,并且有 1 个线程正在调用 counter1.getCount() 和另一个同时调用 counter2.getCount(),那么它们将锁定同一个 Class 对象,一个将阻止另一个。

但如果 2 个线程改为调用 counter1.setCount(...)counter2.setCount(),它们将锁定不同的对象 -- counter1counter2 分别。他们不会互相阻挡。

如前所述,setter 和 getter 不对称是一种非常糟糕的形式,static 是不常见的。

Does that mean when getCount() get called another thread can't access setCount() since the whole class is locked ?

没有。如果 getCount() 被调用,Counter.class 被锁定,当 setCount(...) 被调用时 counter1counter2 被锁定。锁阻塞线程的唯一时间是当同一个对象 已被另一个线程锁定时。仅仅因为 Counter.class 上有一把锁, 就意味着存在某种 super 级锁。唯一会阻塞另一个线程的情况是它也锁定了 Counter.class

我会花点时间阅读 Sun 的 great documentation on how synchronized works .

关于java - 线程获得级别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12064041/

相关文章:

java - 从批处理 JCL 执行 java

java - 系统无法定义java中的特定文件

java - 尝试使用 HttpURLConnection 从 url 读取信息时出现 NullPointerException

java - 如何按顺序优雅地停止java线程?

java - 迭代多线程列表而不同步整个进程

PHP/MySQL 概念数据库 'Sync' 问题

java - Android 中的通用 JSON 解析

c++ - std::conditional_variable::notify_all 不唤醒所有线程

java - 您如何命名 SwingWorker 线程?对代码或最佳实践开放

php - 在 PHP 中将 Firebird 与 MySQL 同步