多线程买票下面的代码为什么会tickets会报错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:19:44 浏览: 111
根据你提供的代码,我们无法确定报错的具体原因。但是,从该代码片段来看,tickets可能因为以下原因报错:
1. tickets对象未初始化:如果在Operate对象的构造函数中没有正确初始化tickets对象,则会导致在sale方法中调用tickets对象的getNum和setNum方法时出现NullPointerException。
2. tickets对象为null:如果在Operate对象的构造函数中没有正确传入tickets对象,则会导致在sale方法中调用tickets对象的getNum和setNum方法时出现NullPointerException。
3. tickets对象在其他线程中已被修改:如果其他线程对tickets对象进行了修改,而没有使用锁来保证同步,则会导致在sale方法中调用tickets对象的getNum和setNum方法时出现线程安全问题。
为了确定具体的原因,需要进一步查看代码,并分析报错信息。
相关问题
找出问题所在改进多线程买票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); } } } }
这段代码存在两个问题:
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);
}
}
}
}
}
```
下面多线程售票tickets为什么报“Cannot resolve symbol 'tickets'”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); } } } }
根据你提供的代码,很可能是因为没有定义变量 tickets。请确认你在代码中是否定义了 tickets 变量,且其类型为一个包含getNum() 和setNum() 方法的类。如果没有定义,可以先定义一个 Ticket 类,并在定义的类中创建一个 Ticket 对象 tickets,作为售票的实例变量。
阅读全文