Java多线程的生命周期,同步互斥锁机制(Lock,synchronized)
2023-12-31 00:24:21
1.线程的生命周期
Java虚拟机中线程分为六个状态,转换关系如下:
①新建
②就绪
③阻塞
④终止
⑤等待
⑥计时等待
运行态(Java虚拟机中没有定义运行状态
)
2.线程的同步
等同于操作系统中进程对临界资源的互斥操作,防止进程发生死锁,从而导致操作系统不安全。
同理线程的同步也是如此。
1.同步代码块
将操作共享数据的代码锁起来。
synchronized(锁)
实现线程的同步互斥。
①锁的状态默认打开,当一个进程占用时,锁自动关闭。
②共享代码全部执行完毕之后,线程出来,锁自动打开。
③锁的定义要唯一
2.同步方法
将
synchronized
关键字加到方法上
特点:①同步方法是锁住方法里面的所有代码。
②锁的对象不能自己指定。
非静态
: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.常见方法
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();
}
}
运行控制台结果:
5.阻塞队列
阻塞队列一共实现了四个接口,从上到下依次是:
阻塞队列有两个实现类:
①ArrayBlockingQueue
:底层是数组,有界。
②LinkedBlockingQueue
:底层是链表,无界,最大为int的最大值。
//创建阻塞队列
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(1);
文章来源:https://blog.csdn.net/qq_61888137/article/details/135278998
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!