java - 同步线程方法并发执行 - 为什么?

标签 java multithreading

我有一个关于线程的问题。我有以下 Thread 类并创建 2 个线程对象。

public class MyThread extends Thread{

    String name="";

    public MyThread(String string) {
        name=string;
    }    

    @Override
    public void run() {
        callMe();
    }       

    synchronized private void callMe() {
        System.out.println("Started");
        for (int i = 1; i <= 5; i++) {
            System.out.println(name+" = "+i);
        }           
    }


    public static void main(String[] args) {            
        MyThread a = new MyThread("A");
        MyThread b = new MyThread("B");

        a.start();
        b.start();
    }       
}

当我执行这个时,我得到的输出是 -

Started
Started
B = 1
B = 2
A = 1
A = 2
B = 3
A = 3
B = 4
A = 4
B = 5
A = 5

我知道 A 和 B 是在线程调度程序选择时随机打印的。

但我的问题是:为什么循环没有一个接一个地执行?我使用了 synchronized 关键字。

最佳答案

你的 synchronized方法是有效的:

private void callMe() {
    synchronized(this) {
        System.out.println("Started");
        for (int i = 1; i <= 5; i++) {
            System.out.println(name+" = "+i);
        }
    }
}

现在您已经创建了两个不同的实例,所以 this每个线程都会不同......所以它们不会相互同步。如果你想看到两个线程使用同一个监视器,你可以像这样重写你的代码:

public final class DemoRunnable implements Runnable {
    @Override
    public synchronized void run() {
        System.out.println("Started");
        for (int i = 1; i <= 5; i++) {
            System.out.println(Thread.currentThread().getName() + " = " + i);
        }
    }

    public static void main(String[] args) {
        Runnable runnable = new DemoRunnable();
        Thread a = new Thread(runnable, "A");
        Thread b = new Thread(runnable, "B");
        a.start();
        b.start();
    }
}

然后你会得到这样的输出:

Started
A = 1
A = 2
A = 3
A = 4
A = 5
Started
B = 1
B = 2
B = 3
B = 4
B = 5

(当然也可以反过来。)

我们仍然有两个线程,但它们在同一个对象上调用同步方法(在本例中为 DemoRunnable),因此一个必须等​​待另一个完成。

几点:

  • 实现 Runnable通常优于扩展 Thread ;更灵活
  • Thread 上同步对象有其自身的问题,如 Thread类(class)自己做;尽量避免它
  • 我个人不喜欢在 this 上同步无论如何——我通常会有一个类型为 Object 的 private final 变量。表示只有我的代码知道的监视器...这样我就可以很容易地看到所有可以在它上面同步的代码,这使得推理更容易

关于java - 同步线程方法并发执行 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26255221/

相关文章:

java - 如何在 parse.com 数据库中追加列

java - java中的LinkedList的LinkedList?

java - 如何等待 JavaRx2 Flowable 完成所有任务?

c# - 有没有办法通过线程名称查询 C# 应用程序中正在运行的线程?

ios - 在 iOS 中暂停事件的后台线程

java - 如何通过 Axios 将 header 发送到 Spring-Boot 应用程序?

java - JSlider Thumb 上方的标签

java : convert List of Bytes to array of bytes

multithreading - 哪个线程安全的JobRepository用于多线程步骤?

java - servlet如何工作?实例化, session ,共享变量和多线程