多线程&JUC:线程的生命周期与安全问题

👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习
🌌上期文章:多线程&JUC:多线程的实现和常用成员方法(守护、礼让、插入线程)
📚订阅专栏:多线程&JUC
希望文章对你们有所帮助

这一部分内容似乎有在面经中看到过,所以做一个小小的总结,线程的安全问题的解决方案在这里不给出解决,给出一个最常见的例子给大家看看,解决方法放在下一篇文章。

线程的生命周期和安全问题

线程的生命周期

所谓生命周期,无非就是线程的所有状态的转化,就像人的一生一样,线程的状态有如下5种:

1、新建:创建线程对象
2、就绪:有执行资格,没有执行权(正在抢CPU执行权,但是不一定抢到)
3、运行:有执行资格,有执行权(抢到了CPU的执行权)
4、死亡:线程死亡,变成垃圾
5、阻塞:没有执行资格,没有执行权(不能去抢CPU的执行权)

而整个过程中,状态转换图如下所示:
在这里插入图片描述
sleep方法会让线程睡眠,睡眠时间到了之后,立马就会执行下面的代码吗?

不会,因为sleep时间到了以后,变回就绪状态,具有抢夺CPU执行权的权利,但是没有抢到之前没办法执行下面的代码。

线程的安全问题

这类问题其实我们之前教javase的老师稍微讲过了一点,演示了会发生的安全问题,但是并没有给出解决的方法,而是当作一个课程练习了。
相信大家也是经常听到这样类似的例子,也就是同时买票的例子,假设有100张票,3个买票窗口,模拟3个线程同时抢票。

线程任务:

public class MyThread extends Thread {

    int ticket = 0;

    @Override
    public void run() {
        while(true){
            if(ticket < 100){
                ++ticket;
                System.out.println(getName() + "正在卖" + ticket + "张票!");
            }else{
                break;
            }
        }
    }
}

测试类:

public class ThreadDemo {
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        MyThread t3 = new MyThread();

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }
}

最后的运行结果显示,出现了超卖现象:
在这里插入图片描述
很显然,ticket这个属性根本没有在共用,所以可以尝试将ticket设置为静态变量使得其变得共用:

static int ticket = 100;

但是运行后发现,除了还会发生多个窗口卖同一张票的问题,ticket甚至还超出了100,后续将会使用同步代码块、同步方法、锁等方式解决这类问题。

其实这类问题放在项目中,做Redis的时候就解决过了,可以看下面文章:
Redis:原理速成+项目实战——Redis实战7(优惠券秒杀+细节解决超卖、一人一单问题)
除了单体情况下,集群情况下也会发生这类线程安全问题,也有相应的解决方案:
Redis:原理速成+项目实战——Redis实战8(基于Redis的分布式锁及优化)

  • 25
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

布布要成为最负责的男人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值