3.多线程的并发问题

多线程在提高运行效率的同时,也带来了并发问题,所谓并发问题就是多线程操作共享资源,导致数据状态异常。
以买票为例,10个人登录了12306,但余票只有5张。

  1. 初始状态有5张票,用户1来买,余票为5,付钱准备出票
  2. 这时用户2也来买,由于票还没出,所以查询发现余票仍未5,付钱准备出票
  3. 此时用户1出票,余票减一变为4
  4. 用户2也出票了,余票减一也变为了4

问题就出在这里,现在实际只有3张票,但余票却显示为4张,余票作为一个共享资源,因为多线程,导致状态异常了,运行下列代码,会发现余票最终成为了负值。

代码示例:

public class Ticket {
    public int total = 5;
    
    public void buy() throws InterruptedException{
        if(total > 0){
            //模拟中间过程
            Thread.sleep(100);
            --total;
        }
    }
    
    public static void main(String[] args) throws InterruptedException {
        Ticket ticket = new Ticket();
        TicketThread ticketThread = new TicketThread(ticket);
        //10个人抢5张票
        for(int i=0;i<10;i++){
            new Thread(ticketThread).start();
        }
        //确保所有线程都执行完了
        Thread.sleep(3000);
        System.out.println("剩余:"+ticket.total);
    }
}
public class TicketThread implements Runnable{
    Ticket ticket = null;
    public TicketThread(Ticket ticket) {
        this.ticket = ticket;
    }
    
    @Override
    public void run() {
        try {
            ticket.buy();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

那如何解决这个问题呢?我们可以为buy()方法加上synchronized关键字,保证某一时刻只能有一个线程在执行buy()方法,这就相当于让多线程排队,强制变成了单线程,这样就可以解决并发问题了。下一节我们将更细致的探讨synchronized关键字。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 写在前面的话: 这篇博客是我从这里“转载”的,为什么转载两个字加“”呢?因为这绝不是简单的复制粘贴,我花了五六个小...
    SmartSean阅读 4,795评论 12 45
  • 讲多线程这个话题,就免不了先了解多线程相关的技术概念。本文涉及到的技术概念有CPU、进程、线程、同异步、队列等概念...
    jackyshan阅读 3,826评论 2 26
  • 人是愿意身处自然之中的,不信你看,许多人家里都喜欢摆放一些绿植,有的是赏叶,有的是观花。 你可知道,家...
    金明啊阅读 354评论 0 1
  • 这次支部书记培训,不仅教业务,而且教方法,增强了全段支部书记的责任感和忠诚履职意识。支部书记纷纷表示,一定以党的十...
    坚持改变2018阅读 139评论 0 0
  • 黎明 梦醒时分 仅留 名称 “鹊桥仙” 什么? 难道是 刘郎织女 相会之 鹊桥? 哦! 今天情人节 鹊桥大仙 开恩...
    兰情二月天阅读 248评论 0 6