线程六个状态:
public enum State {/*** 新生*/NEW,/*** 运行*/RUNNABLE,/***阻塞*/BLOCKED,/*** 等待*/WAITING,/*** 超时等待*/TIMED_WAITING,/**死亡**/TERMINATED;}
synchronized和lock的区别
1、synchronized是关键字,lock是类
2、synchronized全自动获取释放,lock手动
3、synchronized标识后,线程A执行,线程B会一直等待,lock可以中途释放
4、synchronized适合少量的数代码,lock用于大亮代码加锁。
经典问题,生产者、消费者
public static void main(String[] args) {t2 t2 = new t2();new Thread(() -> {for (int i = 0; i < 50; i++) {try {t2.add();} catch (InterruptedException e) {throw new RuntimeException(e);}}}).start();new Thread(() -> {for (int i = 0; i < 50; i++) {try {t2.delete();} catch (InterruptedException e) {throw new RuntimeException(e);}}}).start();}int sum = 0;public synchronized void add() throws InterruptedException {//while(sum==0) if (sum != 0) {this.wait();}sum++;System.out.println(sum + "生产了一个东西");this.notify();}public synchronized void delete() throws InterruptedException {//while(sum==0) if (sum == 0) {this.wait();}sum--;System.out.println(sum + "使用了一个东西");this.notify();}
以上代码看着和用着都没问题,问题出在,一旦我多几个线程运行就会出现数据错误:
而且还有几率一直某一个线程处于等待状态,无法被唤醒 :
我的理解是cpu执行的数据很快,假如在某一刻A线程处于等待,B线程也处于等待,此时C线程唤醒了,这两个同时被唤醒,就出现了多次消费,虚假唤醒,其实就只能消费一次。
所以我们不能使用一次if作为判断,应该使用while作为判断,
然后就是使用java多线程包下的Condition ,它也可以阻塞、唤醒线程,它还有一个优势就是可以指定唤醒某一个线程。
package com.quxiao.controller;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** @program: package1* @author: quxiao* @create: 2023-09-27 15:22**/
public class t3 {public static void main(String[] args) {t3 t3 = new t3();new Thread(() -> {for (int i = 0; i < 10; i++) {t3.a();}}, "a").start();new Thread(() -> {for (int i = 0; i < 10; i++) {t3.b();}}, "b").start();new Thread(() -> {for (int i = 0; i < 10; i++) {t3.c();}}, "c").start();}int sum = 1;Lock lock = new ReentrantLock();Condition aLock = lock.newCondition();Condition bLock = lock.newCondition();Condition cLock = lock.newCondition();void a() {lock.lock();try {while (sum != 1) {aLock.await();}System.out.println(Thread.currentThread().getName()+":" + "AAAA");sum = 2;bLock.signal();} catch (InterruptedException e) {throw new RuntimeException(e);} finally {lock.unlock();}}void b() {lock.lock();try {while (sum != 2) {bLock.await();}System.out.println(Thread.currentThread().getName()+":" + "BBBB");sum = 3;cLock.signal();} catch (InterruptedException e) {throw new RuntimeException(e);} finally {lock.unlock();}}void c() {lock.lock();try {while (sum != 3) {cLock.await();}System.out.println(Thread.currentThread().getName()+":" + "CCCC");sum = 1;aLock.signal();} catch (InterruptedException e) {throw new RuntimeException(e);} finally {lock.unlock();}}
}