自学java碰到些问题,向各位大佬们请教下
多线程安全问题产生的前提 是不是 多线程对共享数据进行了非原子操作
既然是共享数据进行非原子性操作的化,那用AtomicXxx类应该能解决吧
但是....
package Thread_01;
import java.util.concurrent.atomic.AtomicInteger;
class TicketSale2 implements Runnable{
//private int tickets=100;
AtomicInteger tickets=new AtomicInteger(10);
Object object=new Object();
//线程任务为售票,所以将该任务在run方法中执行
public void run(){
while(true) {
//synchronized (object) {
if(tickets.get()>0) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"您好,您的票号为"+tickets.getAndDecrement());
}
else{break;}
//}
}
}
}
public class TicketDemo3 {
public static void main(String[] args) {
//线程任务对象
TicketSale2 ticketSale=new TicketSale2();
//线程对象
Thread t1=new Thread(ticketSale);
Thread t2=new Thread(ticketSale);
Thread t3=new Thread(ticketSale);
Thread t4=new Thread(ticketSale);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
还是会产生线程安全问题...这是为什么呢 还望大佬们抽空解答下
tickets.get() 是原子操作,tickets.getAndDecrement()是原子操作。但是两个操作合起来就不具备原子性了。判断和操作分离了。
Thread-2 , Thread-3, Thread-1 执行tickets.get() 都是1 ,但是sleep20毫秒以后,Thread-2先执行tickets.getAndDecrement()于是打印0,
Thread-3接着执行tickets.getAndDecrement(),但是tickets当前值为0,于是打印-1 ,Thread-1最后执行tickets.getAndDecrement(),但是tickets
的当前值为-1,于是打印-2