为什么我的多线程执行是单线程模式


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级别。

静态同步方法synchronizedClass对象上。如果一个线程正在执行 static synchronized 方法,则尝试执行任何static synchronized方法的所有其他线程都将被阻止,除非锁定线程释放锁。

非静态同步方法在this上同步(表示 Object,它是类的实例(。如果一个线程正在执行 synchronized 方法,则尝试执行任何synchronized方法on that Object (but not the class)的所有其他线程都将被阻止。

查看相关的 SE 问题:

同步块中的静态与非静态锁定对象

同步

和静态同步有什么区别?

您可以在此链接中找到有关概念的良好文档

您可能想知道调用静态同步方法时会发生什么情况,因为静态方法与类而不是对象相关联。在这种情况下,线程获取与类关联的 Class 对象的内部锁。因此,对类静态字段的访问由一个锁控制,该锁不同于类的任何实例的锁。

你应该阅读 Java 中的并发性,特别是 synchronized 关键字的含义。

现在,继续你的代码发生了什么...

当一个线程(例如 id 为 12 的线程(调用 write2() 方法时,它会在对象上获取锁(互斥锁(。然后,它在方法主体(即循环和打印语句(中执行代码。最后,它释放对象上的锁,以允许等待执行该方法的另一个线程。因此,您始终会看到打印语句以两个段的形式出现。

最新更新