java - 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() 同步之后还是如此?
解决方案
同步意味着只有一个线程可以在同一个锁对象上运行标记为同步的代码块(对象实例为同步方法的情况)。这并不意味着线程将按顺序运行。两个线程以任何顺序进入这些同步块是完全正确的,并且在下一个线程之前进入任何次数。您想要的要困难得多,并且超出了简单的同步块可以做的事情。
如果您希望它始终使用线程 A、线程 B、线程 A、线程 B-首先我会质疑这两件事实际上应该是单独的线程。希望事情像这样按顺序运行是您不是异步的第一标志,也不应该是多个线程。但是如果他们这样做了,你可能最好使用两个带有消息处理程序的线程,在允许它们运行时相互发送消息。或者使用信号量相互发送信号。很难给出准确的建议,因为这里的问题显然是更难的事情的简单化版本,没有细节很难猜出正确的实现。
推荐阅读
- javascript - Jestjs - uncaughtException:描述未定义\nReferenceError:描述未定义
- sql - 如何根据sql中的列值将表拆分为两个表?
- javascript - 如何在饼图中添加边框?
- html - 更改选择列表窗口的颜色和位置
- python - 创建一个函数以使用变量生成数据框
- python - 在 scrapy 输出中包含 Excel 工作表中的原始 URL
- android - Gatt 服务器服务列表为空
- javascript - 在 setState 中反应访问范围外的变量
- jekyll - Jekyll - 无法获取 url 和作者姓名
- javascript - 无法使用 Math.round 或 Math.ceil 对数字进行四舍五入