线程的生命周期以及线程同步的加锁(synchronized和Lock)

线程生命周期与同步机制
本文详细解析了线程从新建到死亡的生命周期状态变化,包括就绪、运行、阻塞和死亡等阶段,并深入探讨了线程同步的重要性和实现方式,如synchronized关键字和Lock接口,以及volatile关键字与synchronized的区别。
线程的生命周期
  1. 新建:创建线程对象(new 的过程);
  2. 就绪:有执行资格,但是没有执行权(start());
  3. 运行:有执行资格,有执行权;
      * 阻塞:由于一些操作让线程处于改状态,没有执行资格也没有自行权;
      而另外一些操作可以将它激活,激活后处于就绪状态。
  4. 死亡:线程对象变成垃圾,等待被回收。

在这里插入图片描述

线程同步
1.保护线程安全的一种手段;
2.保证了多线程情况下共享数据不会混乱;
3.同一时间点内,只有一个线程能够进来执行共享数据;

同步的方法 sysnchronized

  1. 同步方法;
      普通方法中的锁对象默认是this,这个类的对象,在重写run方法时,不能锁定this关键字,因为this代表的是本类对象,而不是代码块;
  2. 同步代码块;
      静态方法中的锁对象默认是 当前类名.class;
  3. 同步方法在Thread的子类里面使用,必须加static修饰,锁对象是当前类的对象;
  4. Lock锁机制:
      Lock锁的使用必须结合try{加锁}finally{释放锁},锁对象是当前类对象。
public class TestThread3 implements Runnable {
    int ticketNum = 10;
    static Lock lock = new ReentrantLock();//加Lock锁
    @Override
    public void run() {
        while (true) {
        lock.lock();//如果只是简单的在这里加锁,在输出完解锁,那么程序就会处于死锁状态
            if (ticketNum <= 0) {
                System.out.println("没有票了");//这里没有票了,然后程序直接break,没有解锁,所以,会处于死锁状态
                break;
            }
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "抢到了第" + ticketNum-- + "张票");
            lock.unlock();//解锁
        }
    }

    public static void main(String[] args) {
        TestThread3 thread = new TestThread3();
        new Thread(thread,"黄牛").start();
        new Thread(thread,"小明").start();
        new Thread(thread,"老师").start();

    }
}

程序的运行结果
在这里插入图片描述
但是如果在加锁,解锁的时候加上try {}finally{},就不会,因为finally后面的代码块,总会被执行。

public void run() {
        while (true) {
            try {
                lock.lock();
                if (ticketNum <= 0) {
                    System.out.println("没有票了");
                    break;
                }
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "抢到了第" + ticketNum-- + "张票");
            } finally {
                lock.unlock();
            }
        }
    }

下面截图是程序运行结果,不会造成死锁。
在这里插入图片描述

volatile与sysnchronized区别

  1. 关键字 volatile:能够使变量在值发生改变时,能尽快的让其他线程知道。本质是告诉jvm当前变量在寄存器中的值是不确定的,需要从主存读取;
  2. 关键字 sysnchronized:锁定当前变量,只有当前线程可以访问改变了,其他线程被阻塞;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值