这段java多线程代码有问题吗?

发布于 2022-08-28 11:58:44 字数 434 浏览 15 评论 0

public class Main {
public static void main(String[] args) {
MyThread mt = new MyThread();
new Thread(mt).start();
new Thread(mt).start();
new Thread(mt).start();
}
}

class MyThread implements Runnable {
private int ticket = 20;

public void run() {
for (int i = 0; i < 20; i++) {
if (this.ticket > 0) {
System.out.println("线程:"+Thread.currentThread().getName()+" 卖票:ticket" + this.ticket--);
}
}
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

凯凯我们等你回来 2022-09-04 11:58:44

不知道你想要干什么。不过要是买票,可能下面才是对的。
public synchronized void run() ....

深海夜未眠 2022-09-04 11:58:44

你这个涉及到一个共享变量的问题,ticket变量被三个线程同时访问,就可能导致多个线程读到同样的值,这显然是错误的。而且这只是其中一种情况。更复杂的是--操作并不是原子的,这就会产生另一种情况,如果ticket不是int,而是long,递增/递减是分步进行的,这中间可能另一个线程同时向ticket写值,从而产生更离奇的输出。
所以就要对共享变量进行同步控制,synchronized可以用在方法上,也可以以同步块的方式进行。更简单的上使用java.util.concurrent.atomic.AtomicInteger,它提供原子的递增/递减方法。
而且,在输出的地方也会出问题。因为字符串的拼接也不是原子的,所以肯出现输出混乱的情况。

゛时过境迁 2022-09-04 11:58:44

1楼的建议不错,但是直接对方法加锁的话,性能下降比较严重。。。一般是对ticket这个变量加锁,会好一点。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文