找出问题所在改进多线程买票public class Operate implements Runnable{ int num; public Operate(Tickets tickets) { this.num = tickets.getNum(); } @Override public void run() { sale(); } public synchronized void sale() { if(tickets.getNum() > 0) { try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } if(tickets.getNum() > 0) { int num = tickets.getNum(); System.out.println(Thread.currentThread().getName() + " 正在售卖第 " + num + " 张票,剩余:" + (--num)); tickets.setNum(num); } } } }
时间: 2024-02-14 15:17:52 浏览: 79
多线程同步解决卖票问题
5星 · 资源好评率100%
这段代码存在两个问题:
1. 多线程共享了同一个 Tickets 对象,但是在 Operate 构造函数中获取的 num 只是一个拷贝,而不是引用,所以多个线程间并不共享 num。这会导致多个线程尝试售卖同一张票,从而导致错误。
2. synchronized 锁住的是 sale() 方法,而不是操作共享资源的代码块。这意味着多个线程可以进入 sale() 方法,但是只有一个线程会执行操作共享资源的代码块,从而降低了代码的并发性。
改进方法如下:
1. 在 Operate 中增加一个 Tickets 成员变量,并且在构造函数中将其赋值为传入的 tickets 对象。
2. 将 sale() 方法中的 synchronized 去掉,并且将操作共享资源的代码块用 synchronized 包裹起来。
改进后的代码如下:
```
public class Operate implements Runnable {
private Tickets tickets;
public Operate(Tickets tickets) {
this.tickets = tickets;
}
@Override
public void run() {
sale();
}
public void sale() {
synchronized (tickets) {
if (tickets.getNum() > 0) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (tickets.getNum() > 0) {
int num = tickets.getNum();
System.out.println(Thread.currentThread().getName() + " 正在售卖第 " + num + " 张票,剩余:" + (--num));
tickets.setNum(num);
}
}
}
}
}
```
阅读全文