首页 > 解决方案 > synchronized 关键字不使函数同步:Java

问题描述

我在java中练习多线程并编写了以下代码

class Printer {
    synchronized void printHi(String x) {
        System.out.println(x);
    }
}

class MyThread extends Thread {
    Printer objm;

    MyThread(Printer a) {
        objm = a;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            objm.printHi("MyThread" + i);
        }
    }
}

class YourThread extends Thread {
    Printer objy;

    YourThread(Printer a) {
        objy = a;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            objy.printHi("YourThread" + i);
        }
    }
}

public class test {
    public static void main(String[] args) {
        Printer ob = new Printer();
        MyThread mt = new MyThread(ob);
        YourThread yt = new YourThread(ob);
        mt.start();
        yt.start();
    }
}

有时我得到的输出为:

MyThread0
YourThread0
MyThread1
YourThread1
MyThread2
YourThread2
MyThread3
YourThread3
YourThread4
MyThread4
MyThread5
MyThread6
YourThread5 
MyThread7
YourThread6
MyThread8
MyThread9
YourThread7
YourThread8
YourThread9

这是异步的。为什么即使在使函数 printHi() 同步之后还是如此?

标签: javamultithreadingsynchronized

解决方案


同步意味着只有一个线程可以在同一个锁对象上运行标记为同步的代码块(对象实例为同步方法的情况)。这并不意味着线程将按顺序运行。两个线程以任何顺序进入这些同步块是完全正确的,并且在下一个线程之前进入任何次数。您想要的要困难得多,并且超出了简单的同步块可以做的事情。

如果您希望它始终使用线程 A、线程 B、线程 A、线程 B-首先我会质疑这两件事实际上应该是单独的线程。希望事情像这样按顺序运行是您不是异步的第一标志,也不应该是多个线程。但是如果他们这样做了,你可能最好使用两个带有消息处理程序的线程,在允许它们运行时相互发送消息。或者使用信号量相互发送信号。很难给出准确的建议,因为这里的问题显然是更难的事情的简单化版本,没有细节很难猜出正确的实现。


推荐阅读