qq_41775096
okyesok1515
采纳率100%
2019-01-12 14:40 阅读 631
已采纳

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条回答 默认 最新

  • 已采纳
    songwei1006 舍文 2019-01-12 16:11

    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

    点赞 评论 复制链接分享

相关推荐