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

线程获得级别

邬弘化
2023-03-14

我不清楚的概念

Java Thread 在进入实例同步 java 方法时获取对象级锁,在进入静态同步 Java 方法时获取类级锁。

当它表示对象级锁定和类级锁定时,它意味着什么?

例如:

 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)。这是什么意思?这是否意味着当getCount()被调用时,另一个线程不能访问setCount(),因为整个类都被锁定了?

共有3个答案

班言
2023-03-14

静态成员与类相关联,而不是与特定实例相关联。因此,静态成员上的同步有效地同步了整个类,因为静态是类成员

实例成员与类的实例相关联(例如,内部 this 锁),因此如果您在成员字段(非静态)上同步,那么您将有一个与实例对象关联的锁。

在您的示例中,getCount 在类的内部锁上同步。实际上,您正在执行以下操作:

public setCount(int count){
    synchronized(this){
        this.count = count;
    }  
}

如果您这样做,您将在类级别进行同步:

static Object count = new Object();  
synchronized(count){  

}
巴照
2023-03-14

在 Java 中,每个类和类的每个实例都被赋予了它们的内在锁。这些是在进入和退出同步方法时获取和释放的锁。

像往常一样,< code>this指的是调用< code>setCount()的实例,因为每个实例都有自己的固有锁,所以只要在类的另一个实例上调用第二个对< code>setCount()的调用,就不会阻塞,但是在另一个对< code>setCount()的调用正在进行的实例上调用< code>setCount()的尝试将会阻塞。

类锁和实例锁是不同的,因此getCount()setCount()永远不会相互妨碍。

南宫嘉
2023-03-14

当它表示对象级锁定和类级锁定时,它意味着什么?

当你锁定一个静态方法时,你锁定了类对象本身,每个类加载器都有一个。在您的示例中,

public static synchronized int getCount(){

这是对< code>Counter.class对象的锁定,与以下内容相同:

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

如果改为锁定非静态方法,则锁定拥有该方法的对象实例。在您的示例中:

public synchronized void setCount(int count){

这与锁定特定的计数器实例相同,相当于:

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

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

但是,如果这两个线程分别调用counter1.setCount(…)counter2.setCount()counter1counter2。他们不会互相阻碍。

如前所述,setter和getter上的不对称是非常糟糕的形式,而且不太可能是静态的。

这是否意味着当getCount()被调用时,另一个线程无法访问setCount(),因为整个类都被锁定了?

哈哈如果调用 getCount(),则锁定 Counter.class,当 setCount(...) 调用计数器 1 或计数器 2 时,计数器 2 被锁定。锁阻止线程的唯一时间是同一对象被另一个线程锁定。仅仅因为柜台上有锁.class并不意味着有某种超级级别的锁。唯一会阻止另一个线程的情况是它也锁定在 Counter.class 上。

我会花点时间阅读 Sun 关于同步如何工作的优秀文档。

 类似资料:
  • 我正在编写一个基于await/sleep范式的网络绑定应用程序。 我更喜欢这样一个答案,不创建任何额外的线程

  • 我想实现什么: 用户不活动3分钟后,我想显示一个新的活动。 研究: 我确实在Stackoverflow上查找了这个问题,我发现了一些提示,说明如何使用后台线程执行此操作,创建注册最后一次触摸的基本活动等。 问题: 如果我有超过 20 个活动,则表示 20 个活动,并且我不想从基本活动扩展所有活动。这意味着每次我创建一个新活动时,我都需要扩展这个基础活动,如果我的活动已经从其他一些基础活动扩展,这可

  • 问题描述 (Problem Description) 如何获得运行线程的优先级? 解决方案 (Solution) 以下示例使用setPriority()方法打印正在运行的线程的优先级。 public class SimplePriorities extends Thread { private int countDown = 5; private volatile double d =

  • 我在robolectric(Version1.1)测试案例中获取主UI线程时遇到了麻烦。我正在测试的应用程序方法中有以下检查:

  • 主要内容:1 什么是Java 线程优先级,2 Thread类线程优先级常量,3 Java 线程优先级的例子1 什么是Java 线程优先级 每个线程都有一个优先级。优先级由1到10之间的数字表示。在大多数情况下,线程计划会根据线程的优先级来调度线程(称为抢先式调度)。但是不能保证一定被调用,因为是否被调用取决于JVM选择谁来调度。 2 Thread类线程优先级常量 public static int MIN_PRIORITY public static int NORM_PRIORITY publ

  • 线程的定义是程序的执行路径。每个线程都定义了一个独特的控制流,如果应用程序涉及到复杂且耗时的操作,那幺设置不同的线程执行路径会非常有好处,因为每个线程会被指定于执行特定的工作。 线程实际上是轻量级进程。一个常见的使用线程的实例是现代操作系统中的并行编程。使用线程不仅有效地减少了 CPU 周期的浪费,同时还提高了应用程序的运行效率。 到目前为止我们所编写的程序都是以一个单线程作为应用程序的运行的,其