Java中关于原子变量和多线程安全问题

自学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();

    }
}

还是会产生线程安全问题...这是为什么呢 还望大佬们抽空解答下
图片说明

1个回答

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

qq_41775096
okyesok1515 谢谢老哥
10 个月之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!