Java多线程的生命周期,同步互斥锁机制(Lock,synchronized)

目录

  • 1.线程的生命周期
  • 2.线程的同步
    • 1.同步代码块
    • 2.同步方法
  • 3.Lock锁
  • 4.生产者与消费者问题
    • 1.常见方法
    • 2.等待唤醒机制的代码实现
  • 5.阻塞队列

1.线程的生命周期

Java虚拟机中线程分为六个状态,转换关系如下:
①新建
②就绪
③阻塞
④终止
⑤等待
⑥计时等待

运行态(Java虚拟机中没有定义运行状态)

Java多线程的生命周期,同步互斥锁机制(Lock,synchronized)_第1张图片

2.线程的同步

等同于操作系统中进程对临界资源的互斥操作,防止进程发生死锁,从而导致操作系统不安全。
同理线程的同步也是如此。

1.同步代码块

将操作共享数据的代码锁起来。synchronized(锁)实现线程的同步互斥。
①锁的状态默认打开,当一个进程占用时,锁自动关闭。
②共享代码全部执行完毕之后,线程出来,锁自动打开。
锁的定义要唯一

Java多线程的生命周期,同步互斥锁机制(Lock,synchronized)_第2张图片

2.同步方法

synchronized关键字加到方法上

Java多线程的生命周期,同步互斥锁机制(Lock,synchronized)_第3张图片

特点:①同步方法是锁住方法里面的所有代码。
②锁的对象不能自己指定。
非静态:this,静态:当前类的字节码文件对象。

注:StringBuilder是单线程,不同步的,StringBuffer是多线程,同步的。

3.Lock锁

JDK5以后提供一个新的锁对象Lock。
Lock中提供获得锁和释放锁的方法:
void lock():获得锁
void unlock():释放锁

Lock是接口不能直接实例化的,这里采用它的实现类ReentrantLock来实例化。

    Lock lock = new ReentrantLock();

4.生产者与消费者问题

见博主操作系统专栏中:进程同步互斥之生产者与消费者问题: https://blog.csdn.net/qq_61888137/article/details/133691739

1.常见方法

Java多线程的生命周期,同步互斥锁机制(Lock,synchronized)_第4张图片

2.等待唤醒机制的代码实现

案例:厨师做面条,吃货吃面条,缓冲区为桌子,大小为10。
厨师Cook类:

public class Cook extends Thread {

    @Override
    public void run() {
        while (true) {
            synchronized (Desk.lock) {
                if (Desk.count == 0) {
                    break;
                } else {
                    //判断桌子上是否有事物
                    if (Desk.foodFlag == 1) {
                        //如果有,就等待
                        try {
                            Desk.lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    } else {
                        //如果没有,就制作事物
                        System.out.println("厨师做了一碗面条");
                        //修改桌子上的事物状态
                        Desk.foodFlag = 1;
                        //叫醒等待的消费者开吃
                        Desk.lock.notifyAll();
                    }
                }
            }
        }

    }
}

吃货Foodie类:

public class Foodie extends Thread {
    @Override
    public void run() {

        while (true) {
            synchronized (Desk.lock) {
                if (Desk.count == 0) {
                    break;
                } else {
                    //判断桌子上是否有面条
                    if (Desk.foodFlag == 0) {
                        //没有,继续等待
                        try {
                            Desk.lock.wait();//当前进程和锁进行绑定
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    } else {
                        //总数减一
                        Desk.count--;
                        //有面条就开吃
                        System.out.println("吃货在吃面条,还能再吃" + Desk.count + "碗");
                        //吃完唤醒厨师继续做
                        Desk.lock.notifyAll();
                        //修改桌子状态
                        Desk.foodFlag = 0;
                    }
                }
            }
        }
    }
}

缓冲区桌子Desk类:

public class Desk {
    //是否有面条:1表示有,0表示没有
    public static int foodFlag = 0;
    //总量
    public static  int count = 10;
    //锁对象
    public static Object lock = new Object();
}

主函数main:

public class Main{
    public static void main(String[] args) {
        //创建线程对象
        Cook c = new Cook();
        Foodie f = new Foodie();
        //给线程设置名字
        c.setName("厨师");
        f.setName("吃货");
        //开启线程
        c.start();
        f.start();
    }
}

运行控制台结果:
Java多线程的生命周期,同步互斥锁机制(Lock,synchronized)_第5张图片

5.阻塞队列

阻塞队列一共实现了四个接口,从上到下依次是:

Java多线程的生命周期,同步互斥锁机制(Lock,synchronized)_第6张图片

阻塞队列有两个实现类:
ArrayBlockingQueue:底层是数组,有界。
LinkedBlockingQueue:底层是链表,无界,最大为int的最大值。

        //创建阻塞队列
        ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(1);

你可能感兴趣的:(JavaSE,java,性能优化,开发语言)