Java 中的静态同步

2025年4月8日 | 阅读 6 分钟

虽然同步方法可以确保一次只有一个线程能够访问它,但它不能保证输出顺序,如果方法的执行不是顺序的,或者如果方法本身没有明确地处理执行顺序。

static synchronization

因此,为了保持同步行为,实例级别的锁是不够的;相反,我们需要一个类级别的锁,这可以通过**静态同步**来实现。

换句话说,如果您将任何静态方法设置为同步,那么锁将作用于类,而不是作用于对象。由于我们实现了类级别的锁,一次只有一个线程可以对该方法执行其操作。例如,考虑以下场景。

假设一个类有多个静态同步方法(demo1、demo2、demo3、demo4),一个线程正在访问方法demo1,那么此时其他线程无法访问其他静态同步方法。

语法

为什么需要静态同步?

假设一个共享类(Table)有两个对象,分别命名为object1和object2。对于同步方法和同步块,t1和t2或t3和t4之间不可能发生干扰,因为t1和t2都引用一个具有单一锁的公共对象。

但是,t1和t3或t2和t4之间可能发生干扰,因为t1获取了一个锁,而t3获取了另一个锁。我们不希望t1和t3或t2和t4之间发生干扰。因此,静态同步解决了这个问题。

因此,当我们要确保共享资源以**线程安全的方式**访问时,可以使用静态同步。

静态同步示例

示例

编译并运行

输出

Good Night: Mahi
Good Night: Mahi
Good Night: Mahi
Good Night: Mahi
Good Night: Sachin
Good Night: Sachin
Good Night: Sachin
Good Night: Sachin

Good Night: Mahi
Good Night: Mahi
Good Night: Mahi
Good Night: Mahi
Good Night: Sachin
Good Night: Sachin
Good Night: Sachin
Good Night: Sachin

说明:在上面的程序中,定义了Print、MyThrd和Main三个类,每个类都有

Print类:子线程运行所需的代码

MyThrd类:此类的作用是扩展Thread类,并为Print类的pString类的s赋值,并调用Print类的printMessage()方法。

Main类:它是整个程序的main类,它创建一个子线程

控制流程:我们知道程序的执行始于main方法。首先,我们创建两个子线程并将它们分配给线程的print对象,并在th2.start()语句执行后,将有三个线程(main、th1、th2),执行过程如下:

子线程th1开始执行,由于print()方法是静态同步的,线程th1获得Print类的类级别锁并开始执行printMessage()方法。如果下一个线程到来(在本例中是线程th2),则该线程必须等到前一个线程执行完毕才能获得类级别的锁。

使用匿名类进行静态同步

在此示例中,我们使用匿名类来创建线程。

示例

编译并运行

输出

100
200
300
400
500
600
700
800
900
1000
10
20
30
40
50
60
70
80
90
100
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000
1
2
3
4
5
6
7
8
9
10

类锁上的同步块

该块在由.class名称.class引用的对象的锁上进行同步。Table类中的静态同步方法printTable(int n)等同于以下声明:

同步与静态同步的区别

方面同步静态同步
锁的范围它锁定实例(对象级别)。它锁定类对象(类级别)。
用途它适用于实例方法或块。它适用于静态方法或块。
锁上下文锁与当前对象实例相关联。锁与类的.class对象相关。
线程访问它确保一次只有一个线程能够访问同一对象的同步实例代码。它确保一次只有一个线程能够访问整个类的同步静态代码。
影响它会影响实例级别的线程安全性。它会影响共享静态资源的线程安全性。
用途用于同步实例特定的数据访问。用于同步所有实例的共享数据。
声明synchronized void instanceMethod()static synchronized void staticMethod()
用途它被广泛使用。它不被广泛使用。
实例在同步中,对于每个对象,都会创建一个新实例。在静态同步中,对于整个程序,只有一个实例。

要记住的重要事项

  • 它提供类级别的锁,而不是针对单个对象的锁。
  • 一次只有一个线程可以执行同步的静态方法或块。
  • 类的所有实例共享相同的锁。

结论

在上述讨论中,我们观察到,静态同步方法将锁定类而不是对象,它将锁定类,因为static关键字的意思是:“类而不是实例”。

synchronized关键字的意思是:一次只有一个线程可以访问该方法。

而static synchronized的意思是:一次只有一个线程可以访问该类。


Java静态同步选择题

1. 如何实现类级别锁?

  1. 使用静态同步
  2. 使用同步
  3. 使用多线程
  4. 使用
 

答案:a)

说明:当我们声明一个静态方法为同步时,锁将作用于类,而不是作用于对象。由于我们可以实现类级别的锁,因此一次只有一个线程可以对该方法执行其操作。


2. 静态同步可以应用于?

  1. 仅与静态方法一起使用
  2. 静态方法和静态块
  3. 与多线程一起
  4. 与多线程和静态块一起
 

答案:b)

说明:静态同步只能应用于静态方法和静态块。


3. 有效的静态同步语法是什么?

  1. static synchronized returnType methodName(Type parameters) { }
  2. synchronized static returnType methodName(Type parameters) { }
  3. public static synchronized returnType methodName(Type parameters) { }
  4. public synchronized returnType methodName(Type parameters) { }
  1. 仅i
  2. 仅i和ii
  3. 仅ii和iii
  4. 仅i、ii和iii
 

答案:d)

说明:我们可以使用i、ii和iii语句声明一个静态同步方法。


4. 用于定义静态同步方法的关键字是哪个?

  1. volatile
  2. final
  3. synchronized
  4. transient
 

答案:c)

说明:Java提供synchronization关键字来实现同步。


5. Java中的静态同步确保什么?

  1. 实例级别同步
  2. 类级别同步
  3. 对象级别同步
  4. 线程级别同步
 

答案:b)

说明:静态同步确保类级别的同步。


下一个主题Java中的死锁