1.JUC概念
JUC是文件Java官方文档下面的java.Util下面的工具包。作用于多线程,内容有lock锁,以及callable等内容。JDK官方文档路径。基础多线程不了解可以看多线程子线程结束,执行主线程
2.线程、进程
1.进程:
一个程序是线程集合;
2.线程:
程序执行流的最小单元
Java默认线程两个:main、GC
Java不能自己创建线程,调用我们本地方法库C++来执行创建线程。
1.线程状态
public enum State {NEW,//新建RUNNABLE,//运行BLOCKED,//阻塞WAITING,//等待TIMED_WAITING,//超时等待TERMINATED;//结束}
2.wait、sleep区别
· 来自不同的类
wait —> Object
sleep —> Thread
· 锁释放
wait 释放锁,释放资源,sleep睡眠,不释放资源。
· 适用范围
wait必须在同步代码块中
3.并发、并行
代码获取CPU核心线程数量
Runtime.getRuntime().availableProcessors()
1.并发:
· 多个线程操作一个资源
· 单核CPU,模拟多线程执行抢占资源片,交替执行;
2.并行:
· 多个线程操作多个资源
· 多核CPU,多个线程同时执行;
4.Synchronized锁
synchronized 关键字用于确保多个线程之间对共享资源的安全访问。它可以应用于方法或代码块
1.在方法上使用 synchronized
public synchronized void synchronizedMethod() {// 在这个方法中的代码是线程安全的
}
当一个线程调用了这个方法,其他线程必须等待该方法执行完毕后才能访问它。这确保了对该方法的同步访问,从而避免了并发访问时的数据竞争。
2.在代码块中使用 synchronized:
public void someMethod() {synchronized(this) {// 在这个代码块中的代码是线程安全的}
}
在这种情况下,synchronized 关键字锁定了括号中指定的对象(这里是 this),确保只有一个线程可以同时执行被锁定的代码块。
除了锁定对象本身,还可以使用其他对象作为锁:
public void someMethod() {synchronized(lockObject) {// 在这个代码块中的代码是线程安全的}
}
在这里,lockObject 是一个特定的对象,多个线程可以共享它,并使用它来同步对共享资源的访问。
总之,synchronized 关键字在Java中是用来实现线程安全的重要工具,它可以确保对共享资源的访问是同步的,从而避免了多线程环境下的竞态条件。
5.Lock锁
Lock是一种用于实现线程同步的机制。与传统的synchronized关键字相比,Lock提供了更灵活的、可扩展的锁定操作。Lock接口定义了一组用于获取和释放锁的方法,常用的实现类是ReentrantLock。
Lock lock = new ReentrantLock();
lock.lock(); // 获取锁try {//业务逻辑} finally {lock.unlock(); // 释放锁}
6.Synchronized锁与Lock锁区别
1.Synchronized 内置的]ava关键字, Lock 是一个java类
2.Synchronized 无法判断获取锁的状态,Lock 可以判断是否获取到了锁
3.Synchronized 会自动释放锁,lock 必须要手动释放锁!如果不释放锁,死锁
4.Synchronized 线程1(获得锁,阻塞)、线程2(等待,傻傻的等);Lock锁就不一定会等待下去;
5.Synchronized可重入锁,不可以中断的,非公平;Lock,可重入锁,可以判断锁,非公平(可以自己设置);
6.Synchronized 适合锁少量的代码同步问题,Lock 适合锁大量的同步代码!
7.线程通信
1.先判断线程是否需要等待;
2.编写业务;
3.通知其他线程执行;
Synchronized实现
注意: if是一次判断,所以我们需要用while
class Data{private int number = 0;//number +1public synchronized void increment() throws InterruptedException {//用while可以防止虚假唤醒 如果我们使用全部唤醒notifyAll 采用notify也不会造成虚假唤醒while (number != 0){//线程等待this.wait();}//业务逻辑number++;System.out.println(Thread.currentThread().getName() + "---number:" + number);//启动其他线程this.notifyAll();}//number -1public synchronized void decrement() throws InterruptedException {while (number == 0){//线程等待this.wait();}//业务逻辑number--;System.out.println(Thread.currentThread().getName() + "---number:" + number);//启动其他线程this.notifyAll();}
}
public class App {public static void main(String[] args) {//获取CPU核心//CPU密集型,I/O密集型System.out.println(Runtime.getRuntime().availableProcessors());System.out.println("Hello World!");commThread();}public static void commThread() {Data data = new Data();new Thread(() -> {try {for (int i = 0; i < 10; i++) {data.increment();}} catch (InterruptedException e) {throw new RuntimeException(e);}}, "aaa").start();new Thread(() -> {try {for (int i = 0; i < 10; i++) {data.decrement();}} catch (InterruptedException e) {throw new RuntimeException(e);}}, "bbb").start();new Thread(() -> {try {for (int i = 0; i < 10; i++) {data.increment();}} catch (InterruptedException e) {throw new RuntimeException(e);}}, "ccc").start();new Thread(() -> {try {for (int i = 0; i < 10; i++) {data.decrement();}} catch (InterruptedException e) {throw new RuntimeException(e);}}, "ddd").start();}}
Lock实现
注意: condition可以有多个监视多个线程,从而指定唤醒指定线程。
class LockData {private int number = 0;private Lock lock;private Condition condition;public LockData(){this.lock = new ReentrantLock();this.condition = lock.newCondition();}//condition.await(); 相当于this.wait();//condition.signalAll(); 相当于this.notifyAll();//number +1public void increment() throws InterruptedException {lock.lock();try {while (number != 0){//线程等待condition.await();}//业务逻辑number++;System.out.println(Thread.currentThread().getName() + "---number:" + number);//启动其他线程condition.signalAll();}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}//number -1public void decrement() throws InterruptedException {lock.lock();try {while (number == 0){//线程等待condition.await();}//业务逻辑number--;System.out.println(Thread.currentThread().getName() + "---number:" + number);//启动其他线程condition.signalAll();}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}
}
public class App {public static void main(String[] args) {//获取CPU核心//CPU密集型,I/O密集型System.out.println(Runtime.getRuntime().availableProcessors());System.out.println("Hello World!");commThread();}public static void commThread() {LockData lockData = new LockData();new Thread(() -> {for (int i = 0; i < 10; i++) {try {lockData.increment();} catch (InterruptedException e) {throw new RuntimeException(e);}}}, "aaa").start();new Thread(() -> {for (int i = 0; i < 10; i++) {try {lockData.decrement();} catch (InterruptedException e) {throw new RuntimeException(e);}}}, "bbb").start();new Thread(() -> {for (int i = 0; i < 10; i++) {try {lockData.increment();} catch (InterruptedException e) {throw new RuntimeException(e);}}}, "ccc").start();new Thread(() -> {for (int i = 0; i < 10; i++) {try {lockData.decrement();} catch (InterruptedException e) {throw new RuntimeException(e);}}}, "ddd").start();}
}
不足之处望海涵