【问题标题】:synchronized keyword not making the function synchronized: Java [duplicate]同步关键字不使函数同步:Java [重复]
【发布时间】:2021-10-26 19:28:38
【问题描述】:

我在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() 设置为同步后还是这样?

【问题讨论】:

  • synchronization != order
  • 顺序与并发相反。你想要第一个但使用第二个。

标签: java multithreading synchronized


【解决方案1】:

您正在同步 printHi 函数调用。这意味着同一对象上的两个printHi 实例不会同时运行。那太棒了。这意味着你永远不会得到这样的输出

MyThYourThreadread77

(旁注:如果我没记错的话,Java 的打印原语已经有些同步了,所以无论如何都不应该发生这种情况。但出于演示目的,它会这样做)

但是,您的循环不同步。如果您希望 整个 循环一次只发生在一个线程中,请从 print 中删除 synchronized 并将循环编写为

synchronized (objm) {
    for (int i = 0; i < 10; i++) {
        objm.printHi("MyThread" + i);
    }
}

(对于YourThread 中的objy 也是如此)

仍然不能保证哪个会先发生,但在这种情况下,两个循环不会相互中断。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2022-12-19
      • 2012-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-01
      • 2021-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多