1.JUC概述
2.Lock接口
使用lock锁实现;
3.多线程编程(Synchronized和Lock)
使用synchronized实现多线程编程:
package sync;
//第一步 创建资源类,定义属性和操作方法
public class Share {
//初始值
private int number=0;
//+1的方法
public synchronized void incr() throws InterruptedException {
//第二部 判断 干活 通知
while (number != 0) { //判断number值是否是0,如果不是0,原地等待
this.wait();
}
//如果是number值是0,就+1操作
number++;
System.out.println(Thread.currentThread().getName() + "::" + number);
//通知其他线程
this.notifyAll();
}
//-1的方法
public synchronized void decr() throws InterruptedException {
while (number != 1) {
this.wait();
}
//干活
number--;
System.out.println(Thread.currentThread().getName() + "::" + number);
this.notifyAll();
}
public static void main(String[] args) {
//第三部:创建多个线程,调用资源类的操作方法
lock.Share share = new lock.Share();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
share.incr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "AA").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
share.decr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "BB").start();
}
}
使用lock实现多线程编程:
package lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Share {
private int number=0;
//创建lock
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
//+1的方法
public void incr() throws InterruptedException {
//上锁
lock.lock();
while (number != 0) {
condition.await();
}
//干活
number++;
System.out.println(Thread.currentThread().getName() + "::" + number);
//通知
condition.signalAll();
try {
}finally {
//解锁
lock.unlock();
}
}
//-1的方法
public void decr() throws InterruptedException {
//上锁
lock.lock();
while (number != 1) {
condition.await();
}
//干活
number--;
System.out.println(Thread.currentThread().getName() + "::" + number);
//通知
condition.signalAll();
try {
}finally {
//解锁
lock.unlock();
}
}
public static void main(String[] args) {
Share share = new Share();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
share.incr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "AA").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
share.decr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "BB").start();new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
share.incr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "CC").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
share.decr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "DD").start();
}
}
线程间定制化通信:
package lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//第一步 创建资源来
class ShareResource{
//定义标志位
private int flag = 1;
//创建lock锁
private Lock lock = new ReentrantLock();
//创建三个condition
private Condition c1 = lock.newCondition();
private Condition c2 = lock.newCondition();
private Condition c3 = lock.newCondition();
//打印5次,参数第几轮
public void print5(int loop) throws InterruptedException {
//上锁
lock.lock();
try {
//判断
while (flag != 1) {
//等待
c1.await();
}
//干活
for (int i = 0; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + "::" + i + ":轮数:" + loop);
}
//通知
flag = 2;//修改标志位2
c2.signal();
}finally {
//解锁
lock.unlock();
}
}
//打印10次,参数第几轮
public void print10(int loop) throws InterruptedException {
//上锁
lock.lock();
try {
//判断
while (flag != 2) {
//等待
c2.await();
}
//干活
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "::" + i + ":轮数:" + loop);
}
//通知
flag = 3;//修改标志位3
c3.signal();
}finally {
//解锁
lock.unlock();
}
}
//打印15次,参数第几轮
public void print15(int loop) throws InterruptedException {
//上锁
lock.lock();
try {
//判断
while (flag != 3) {
//等待
c3.await();
}
//干活
for (int i = 0; i < 15; i++) {
System.out.println(Thread.currentThread().getName() + "::" + i + ":轮数:" + loop);
}
//通知
flag = 1;//修改标志位1
c1.signal();
}finally {
//解锁
lock.unlock();
}
}
}
public class ThreadDemo3 {
public static void main(String[] args) {
ShareResource shareResource = new ShareResource();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
shareResource.print5(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"AA").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
shareResource.print10(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"BB").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
shareResource.print15(15);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"CC").start();
}
}
4.集合的线程安全
ArrayList 线程不安全
解决方案:
源码分析:
hashset 无序,不能重复,线程不安全:
hashMap线程不安全
5.多线程锁
什么是死锁
代码演示死锁:
6.Callable
7.JUC强大的辅助类
8.ReentrantReadWriteLock 读写锁
悲观锁 效率低,不支持并发操作
乐观锁:通过版本号控制
行锁 :可能会发生死锁
package readwrite;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
class MyCache {
//创建map集合
private volatile Map<String, Object> map = new HashMap<>();
//创建读写锁
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
//放数据
public void put(String key, Object value) {
//添加写锁
readWriteLock.writeLock().lock();
//暂停一会
try {
System.out.println(Thread.currentThread().getName() + "正在写操作" + key);
TimeUnit.MICROSECONDS.sleep(300);
//放数据
map.put(key,value);
System.out.println(Thread.currentThread().getName() + "写完了" + key);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//释放写锁
readWriteLock.writeLock().unlock();
}
}
//取数据
public void get(String key) {
//添加读锁
readWriteLock.readLock().lock();
//暂停一会
try {
Object result = null;
System.out.println(Thread.currentThread().getName() + "正在读取操作" + key);
TimeUnit.MICROSECONDS.sleep(300);
result = map.get(key);
System.out.println(Thread.currentThread().getName() + "取完了" + key);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放读锁
readWriteLock.readLock().unlock();
}
}
}
public class ReadWriteLockDemo {
public static void main(String[] args) {
MyCache myCache = new MyCache();
//创建线程放数据
for (int i = 0; i < 5; i++) {
final int num = i;
new Thread(()->{
myCache.put(num + "", num + "");
},String.valueOf(i)).start();
}
//创建线程取数据
for (int i = 0; i < 5; i++) {
final int num = i;
new Thread(()->{
myCache.get(num + "");
},String.valueOf(i)).start();
}
}
}
1
9.阻塞队列
阻塞队列的架构:
10.ThreadPool
底层的工作流程:
自定义线程池:
11. Fork/Join
代码演示:
12.CompletableFuture 异步回调