最近在学juc高并发编程,现在在这里分享一下我的学习笔记,供大家参考参考哦
juc的全称是java并发包(Java.util.concurrent)
关于线程:
线程的几个状态:
//新建
NEW,
//运行
RUNNABLE,
//阻塞
BLOCKED,
//等待(无限期等待)
WAITING,
//超时等待
TIMED_WAITING,
//终止
TERMINATED;
wait和sleep区别
1、来自不同类
wait=>Object
sleep=>Thread
2、关于锁的释放
wait会释放锁,sleep不会释放锁,等于是抱着锁睡觉
3、使用范围
wait:必须在同步代码块中
sleep:可以出现在任何地方
4、都需要捕获异常
lock锁
Lock接口
公平锁:十分公平,先来后到
非公平锁:十分不公平,可以插队(synchronized和lock锁默认都是非公平锁)
Synchronized和Lock锁的区别
1、Synchronized是java内置的关键字,Lock是一个java接口
2、Synchronized无法判断锁的状态,Lock可以判断是否获取到锁
3、Synchronized会自动释放锁,Lock需要手动释放锁,如果不释放则会造成死锁
4、Synchronized 线程1获得锁线程2会永远等待,Lock锁就不一定会等待下去
5、Synchronized 可重入锁,不可以中断,非公平;Lock,可重入锁,可以判断锁,可以自己设置公不公平,默认非公平
6、Synchronized 适合锁少量的代码同步问题,Lock锁适合锁大量的同步代码
生产者和消费者问题
Synchronized版:wait notify
生产者和消费者问题 Synchronized版:
用while防止虚假唤醒
package com.lai.productAndconsummer;
/**
* @author lly
* @version 1.0
* @date 2021/12/7 15:55
*/
/**
* 线程之间的通信问题:生产者和消费者问题 等待唤醒,通知唤醒
* 线程交替执行 A B操作同一个变量 num=0
*
*/
public class Test01 {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B").start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"C").start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"D").start();
}
}
class Data{ //数字资源类
private int number=0;
//+1
public synchronized void increment() throws InterruptedException {
while (number!=0){
//等待
this.wait();
}
number++;
System.out.println(Thread.currentThread().getName()+"线程进来啦=>"+number);
//通知其他线程+1完毕
this.notifyAll();
}
//-1
public synchronized void decrement() throws InterruptedException {
while (number==0){
//等待
this.wait();
}
number--;
System.out.println(Thread.currentThread().getName()+"线程进来啦=>"+number);
//通知其他线程-1完毕
this.notifyAll();
}
}
生产者消费者问题,JUC版
代码实现
package com.lai.productAndconsummer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author lly
* @version 1.0
* @date 2021/12/7 17:48
*/
public class TestJuc {
public static void main(String[] args) {
Data2 data = new Data2();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B").start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"C").start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"D").start();
}
}
class Data2{ //数字资源类
private int number=0;
Lock lock=new ReentrantLock();
Condition condition = lock.newCondition();
// condition.await(); //等待
// condition.signalAll(); //唤醒全部
//+1
public void increment() throws InterruptedException {
lock.lock();
try {
//业务代码
while (number!=0){
//等待
condition.await();
}
number++;
System.out.println(Thread.currentThread().getName()+"线程进来啦=>"+number);
//通知其他线程+1完毕
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
//-1
public void decrement() throws InterruptedException {
lock.lock();
try {
while (number==0){
//等待
condition.await();
}
number--;
System.out.println(Thread.currentThread().getName()+"线程进来啦=>"+number);
//通知其他线程-1完毕
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
lock锁可以通过condition精准地通知和唤醒线程:
package com.lai.productAndconsummer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author lly
* @version 1.0
* @date 2021/12/7 18:51
* 顺序执行
*/
public class Test03 {
public static void main(String[] args) {
Data3 data3 = new Data3();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
data3.printA();
}
},"A").start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
data3.printB();
}
},"B").start();
new Thread(()->{
for (int i = 0; i <20 ; i++) {
data3.printC();
}
},"C").start();
}
}
class Data3{ //资源类 Lock
private int number=1; //1A 2B 3C
private Lock lock=new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
public void printA(){
lock.lock();
try {
//业务,判断,执行,通知
while (number!=1){
condition1.await();
}
System.out.println(Thread.currentThread().getName()+"=>AAAAA执行了");
//唤醒指定的人
condition2.signal();
number=2;
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printB(){
lock.lock();
try {
//业务,判断,执行,通知
while (number!=2){
condition2.await();
}
System.out.println(Thread.currentThread().getName()+"=>BBBBB执行了");
//唤醒指定的人
number=3;
condition3.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printC(){
lock.lock();
try {
//业务,判断,执行,通知
while (number!=3){
condition3.await();
}
System.out.println(Thread.currentThread().getName()+"=>CCCCC执行了");
//唤醒指定的人
number=1;
condition1.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
今天关于juc中lock锁的问题就先讲到这里啦,下期和小伙伴萌分享八锁问题~