【java】JUC并发编程

在这里插入图片描述

线程基础

在这里插入图片描述
在这里插入图片描述

创建线程的方式

1. 继承Thread类

继承Thread类、重写run方法、new 自定义的Thread的继承类、t.start启动线程。
注意是start启动而不是run启动。调用run就相当于调用一个普通的方法。

2. 实现Runnable接口

实现Runnable接口、重写run方法、创建Runnable实现类的实例myRunnable、创建Thread对象依赖myRunnable、t.start启动线程

MyRunnable mr = new MyRunnable();
Thread t1 = new Thread(mr);
Thread t2 = new Thread(mr);

t1.start();
t2.start();

3. 实现Callable接口

该方式可以接收线程的返回值。
实现Callable接口,有泛型规定返回值类型、重写call方法、创建MyCallable对象mc、创建FutureTask对象ft,用来接收返回值,同时需要依赖mc、创建Thread对象依赖ft、调用t.start启动线程、ft.get接收返回值

public class MyCallable implements Callable<String> { // 返回值类型是String
	// 重写call方法,可以抛异常
}

// 开线程
MyCallable mc = new MyCallable();
FutureTask<String> ft = new FutureTask<String>(mc);

Thread t = new Thread(ft);
t.start();

String result = ft.get();

4. 创建线程池

后面详细讲解。
实现Runnable接口、重写run方法、创建线程池对象、submit方法提交任务、关闭线程池。

在这里插入图片描述
在这里插入图片描述

线程状态

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

保证线程按顺序执行

在这里插入图片描述

Notify和NotifyAll区别

在这里插入图片描述
唤醒的都是wait等待状态的线程。

wait和sleep区别

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

如何停止一个正在运行的线程?

在这里插入图片描述

  1. 退出标志

在这里插入图片描述
只打印了两次:
在这里插入图片描述

  1. Stop强制终止线程

在这里插入图片描述

  1. interrupted

打断阻塞(sleep)的线程
在这里插入图片描述
在这里插入图片描述

打断正常线程
在这里插入图片描述
在这里插入图片描述
调用interrupt方法修改了isInterrupted,从false变true,因此线程退出。

线程中的并发安全

sychronized底层原理

Synchronized【对象锁】采用互斥的方式让同一时刻至多只有一个线程能持有【对象锁】,其它线程再想获取这个【对象锁】时就会阻塞住。

Object lock = new Object(); // 对象锁
// ... 
public void test() {
	sychronized(lock) {
		// ...
	}
}

在这里插入图片描述
在这里插入图片描述
Thread1释放了锁对象后,会唤醒EntryList中的所有线程,来争抢这个锁。注意:阻塞队列中是没有排队的,不是按照顺序发放锁。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

重量级锁、轻量级锁、偏向锁、锁升级

Synchronized是重量级锁:jvm是系统级别,属于内核态,因此涉及用户态和内核态切换、进程上下文切换,成本高,性能低。
在JDK 1.6引入了两种新型锁机制:偏向锁轻量级锁,它们的引入是为了解决在没有多线程竞争或基本没有竞争的场景下因使用传统锁机制带来的性能开销问题。
比如T1获得了锁,执行完了释放,后面还是他获得了这个锁,一个线程重复获得同一把锁!使用Synchronized性能低。
在这里插入图片描述
在这里插入图片描述
每个java 对象都可以关联一个 Monitor对象,如果使用 synchronized 给对象上锁(重量级)之后,该对象头Mark Word 中就被设置指向 Monitor 对象的指针。

在这里插入图片描述
在这里插入图片描述
释放锁时:锁记录=null表明这是一把重入锁,则直接-1,即删除这条Lock Record。锁记录≠null表明不是重入锁,则再来一次CAS交换地址。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
一旦锁发生了竞争,都会升级为重量级锁!

JMM Java内存模型

注意不要混淆Java内存结构!
在这里插入图片描述
在这里插入图片描述

CAS

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Volatile

在这里插入图片描述

  • 线程可见性:用 volatile 修饰共享变量,能够防止编译器等优化发生,让一个线程对共享变量的修改对另一个线程可见。

在这里插入图片描述

  • 防止指令重排:用 volatile 修饰共享变量会在读、写共享变量时加入不同的屏障,阻止其他读写操作越过屏障,从而达到阻止重排序的效果。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

AQS

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ReentrantLock

在这里插入图片描述
基本语法:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

synchronized与lock的区别

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
一开始主线程获得了锁,T1也想要获得就会进入阻塞等待。调用了interrupt之后就会打断T1,不获得锁了。
在这里插入图片描述
tryLock获取锁失败之后会直接放弃!而不会阻塞等待。
在这里插入图片描述
可以通过参数设置等多长时间,如上是等待两秒钟。
多条件变量:可以唤醒锁。
在这里插入图片描述

ConcurrentHashMap

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

线程池

使用线程池:线程创建和销毁的开销都很大。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
保证了执行顺序。
在这里插入图片描述
适合任务书密集,但执行时间都很短。
在这里插入图片描述
在这里插入图片描述

ThreadLocal

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值