package indi.JavaLearn;
public class MultiThread {
private static int shared;
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
(new Thread() {
public void run() {
write2();
}
}).start();
}
}
public synchronized static void write2() {
int i = 0;
while (i < 2) {
shared++;
System.out.println("write," + Thread.currentThread().getId() + "," + String.valueOf(shared));
i++;
}
}
}
结果
write,12,1
write,12,2
write,15,3
write,15,4
write,16,5
write,16,6
write,14,7
write,14,8
write,13,9
write,13,10
write2
中的同步修饰符允许该方法一次只能由一个线程运行 - 您需要删除它才能同时在多个线程上运行。
如果您真正想做的是锁定共享变量,请使用synchronized
块:
synchronized(shared){
shared++;
System.out.println("write," + Thread.currentThread().getId() + "," + String.valueOf(shared));
}
public synchronized static void write2()
是一种静态同步方法,这意味着锁定/监视器保持在Class
级别而不是Object
级别。
静态同步方法synchronized
在Class
对象上。如果一个线程正在执行 static synchronized
方法,则尝试执行任何static synchronized
方法的所有其他线程都将被阻止,除非锁定线程释放锁。
非静态同步方法在this
上同步(表示 Object,它是类的实例(。如果一个线程正在执行 synchronized
方法,则尝试执行任何synchronized
方法on that Object (but not the class)
的所有其他线程都将被阻止。
查看相关的 SE 问题:
同步块中的静态与非静态锁定对象
同步和静态同步有什么区别?
您可以在此链接中找到有关概念的良好文档
您可能想知道调用静态同步方法时会发生什么情况,因为静态方法与类而不是对象相关联。在这种情况下,线程获取与类关联的 Class 对象的内部锁。因此,对类静态字段的访问由一个锁控制,该锁不同于类的任何实例的锁。
你应该阅读 Java 中的并发性,特别是 synchronized
关键字的含义。
现在,继续你的代码发生了什么...
当一个线程(例如 id 为 12 的线程(调用 write2()
方法时,它会在对象上获取锁(互斥锁(。然后,它在方法主体(即循环和打印语句(中执行代码。最后,它释放对象上的锁,以允许等待执行该方法的另一个线程。因此,您始终会看到打印语句以两个段的形式出现。