当前位置: 首页 > 知识库问答 >
问题:

synchronized(this)只锁定synchronized块还是所有“this”代码?

冷宏茂
2023-03-14
public class ObjectCounter {
    private static long numOfInstances = 0;
    public ObjectCounter(){
        synchronized(this){
        numOfInstances++;
        }
    }
    **public static synchronized long getCount(){
        return numOfInstances;
    }**
//vs//
    **public static long getCount(){
        return numOfInstances;
    }**
}

如果我只运行几个线程,其中一些线程调用静态函数getcount(),而另一些线程创建新实例。我希望在每次对getcount()的调用中获得当时实例的实际数量。

  1. 代码中的两个选项有区别吗?
  2. 如果我锁定“this”,这是否意味着在构造函数退出synchronized块之前,我不能调用getCount()(假设我没有在getCount()上编写synchronize)。
  3. 如果我在代码中的某个地方执行同步块,它是只锁定同步块还是锁定所有“this”代码?
  4. 从这里开始编辑:谢谢大家,这很有帮助,但在你们的回答之后,我还有几个问题。
  5. 如果我理解正确的话,synchronized(this)块不影响(或连接到)静态synchronized函数(用锁术语来说,不是NumoFinestens增量)?
  6. 是否有更好的选择使增量和getCount()函数是线程安全的?(就像打开一个静态对象,然后执行synchronized(obj)而不是synchronized(this)--朋友建议的)。
  7. 如果我在ObjectCounter类中有一个f1()方法(非静态),当一个线程在synchronized(this)中时,其他线程是否可以进入f1()块(不是synchronized类或内部有synchronized块)?
  8. 如果ObjectCounter中有f1()方法(非静态)和f2()方法(非静态),那么在f1()中,我已经同步了(this)块。当一个线程在synchronized(this)块中时,其他线程是否可以进入f1()块(不是synchronized类或内部有synchronized块)?(假设两个线程“工作”在同一个实例上)

共有1个答案

董弘新
2023-03-14

使用synchronized意味着为了让线程执行该块或方法,它必须获得由该块或方法(显式或隐式)引用的锁。对于Static Synchronized方法,该锁是类对象上的监视器。对于synchronized(this)块,使用的锁是当前实例上的监视器。在多个方法或块之间共享锁可以增强更新的原子性和内存可见性,共享锁还提供了一个共享的通信路径,通过该路径可以进行等待和通知。

由于静态同步块使用的锁与构造函数中的块使用的锁不同,因此进入静态同步块不会被另一个线程访问需要获取当前实例上的锁的块所阻止,并且构造函数中的同步块对任何事情都没有影响,因此锁的获取将始终是无争用的。这里更重要的是,构造函数中的一个线程所做的更改可能不会被使用getter的其他线程看到。同步会影响锁定和内存可见性。

这个更改后的版本可以工作:

public class ObjectCounter {
    private static long numOfInstances = 0;
    public ObjectCounter(){
        synchronized(ObjectCounter.class){
            numOfInstances++;
        }
    }
    public static synchronized long getCount(){
        return numOfInstances;
    }
}

问题#3、#7和#8看起来非常相似:如果一个方法/块没有试图获取锁,那么没有什么可以阻止线程执行该方法/块。对象作为一个整体没有得到任何保护,使用同步的方法或块来强制锁定是保护的内容。少考虑“使用synchronized关键字”,多考虑线程需要获取什么锁。

 类似资料:
  • 问题内容: 如果您打开Python解释器,然后输入“ import this”,您将知道: 提姆·彼得斯(Tim Peters)撰写的《 Python之禅》 美丽胜于丑陋。 显式胜于隐式。 简单胜于复杂。 复杂胜于复杂。 扁平比嵌套更好。 稀疏胜于密集。 可读性很重要。 特殊情况不足以违反规则。 尽管实用性胜过纯度。 错误绝不能默默传递。 除非明确地保持沉默。 面对模棱两可的想法,拒绝猜测的诱惑。

  • 当锁被释放后,任何一个线程都有机会竞争得到锁,这样做的目的是提高效率,但缺点是可能产生线程饥饿现象。

  • 我知道我做错了什么,因为这很奇怪,我学习PHPUnit已经有几天了。测试主题是控制器操作: 当控制器抛出事件时,我需要模拟一个事件订阅服务器(实现)。有一个静态方法。测试方法帮助程序(获取模拟):

  • 问题内容: 我遵循了有关创建JavaScript秒表,并试图将其扩展为可与多个秒表(一个类的多个实例)一起使用。我遇到的问题是,当我试图在时钟滴答声中显示当前值时,我需要使用“this”对类实例进行硬编码,这是行不通的(在我使用console.log的那一行中)。我已将代码缩减到最低限度以尝试理解这一方面,并​​粘贴了以下内容: 我认为以下链接描述了我的问题,但我对它的理解不足以在此处应用。问题是

  • 问题内容: 我对关键字的用法和重要性有一些疑问。 synchronized关键字的意义是什么? 方法synchronized什么时候应该? 从程序上和逻辑上是什么意思? 问题答案: 该关键字是所有不同的线程读取和写入相同的变量,对象和资源。这不是Java中的琐碎话题,但以下是Sun的引文: 方法提供了一种防止线程干扰和内存一致性错误的简单策略:如果一个对象对一个以上线程可见,则对该对象变量的所有读

  • 一、线程同步问题的产生及解决方案 问题的产生: Java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查),将会导致数据不准确,相互之间产生冲突。 如下例:假设有一个卖票系统,一共有100张票,有4个窗口同时卖。 public class Ticket implements Runnable { // 当前拥有的票数 private int num =