public enum State{
NEW,//新建
RUNNABLE,//就绪
BLOCKED,//阻塞
WAITING,//一直等待
TIMED_WAITTING,//超时等待
TERMINATED;//终结
}
public static void main(String[] args) {
Thread threadName = new Thread(() -> {
System.out.println(Thread.currentThread().getName()
+ "::"+Thread.currentThread().isDaemon());
while (true) {
}
}, "threadName");
threadName.start();//用户线程
System.out.println(Thread.currentThread().getName()+"::"+"over");//主线程
}
//设置守护线程
threadName.setDaemon(true);
threadName.start();
多线程编程过程(高内聚)
synchronized 是Java中的关键字,是一种同步锁 可修饰
3个售票员,卖出30张票
public class Ticket {
/**
* 票数
*/
private Integer number = 30;
/**
* 卖票方法 基础版本
* 使用同步监视器 synchronized
*/
public synchronized void saleV1() {
//判断 是否有票
if (number > 0) {
System.out.println(Thread.currentThread().getName() +
": 卖出 " + number-- + ",剩下" + number);
}
}
}
public class SaleTicket {
//step2
public static void main(String[] args) {
//创建Ticket对象
Ticket ticket = new Ticket();
//创建线程
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 40; i++) {
ticket.saleV1();
}
}
},"sale01");
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 40; i++) {
ticket.saleV1();
}
}
},"sale02");
Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 40; i++) {
ticket.saleV2();
}
}
},"sale03");
thread1.setPriority(1);
thread2.setPriority(5);
thread1.start();
thread2.start();
thread3.start();
}
}
API->java.utils-concurrent.locks
public class Ticket {
/**
* 可重入锁 对象
*/
private final ReentrantLock lock = new ReentrantLock();
/**
* 票数
*/
private Integer number = 30;
/**
* 卖票方法 手动锁管理版本
* 使用可重入锁 对象 lock上锁,unlock解锁
*/
public void saleV2() {
lock.lock();//上锁
try {
//判断
if (number > 0) {
System.out.println(Thread.currentThread().getName() +
": 卖出 " + number-- + ",剩下" + number);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();//解锁
}
}
}
public class SyncThreadCommunicationShareResource {
/**
* 初始值
*/
private Integer number = 0;
/**
* 加1的方法
*/
public synchronized void increment() throws InterruptedException {
//判断
if (number != 0) {//判断number值是否是0,是0干活,不是0等待
//对于某一个参数的版本,实现中断和虚假唤醒是可能的,
// 此方法应存在于循环中,在非循环代码中存在虚假唤醒问题
this.wait();
}
//干活
this.number++;//number为0执行++
System.out.println(Thread.currentThread().getName() + "::"+this.number);
//通知
this.notifyAll();
}
/**
* 减1的方法
*/
public synchronized void decrement() throws InterruptedException {
//判断
if (number != 1) {
this.wait();
}
//干活
this.number--;
System.out.println(Thread.currentThread().getName() + "::"+this.number);
//通知
this.notifyAll();
}
}
public class SyncThreadCommunicationDemo {
public static void main(String[] args) {
SyncThreadCommunicationShareResource shareResource = new SyncThreadCommunicationShareResource();
/**
* 创建线程
*/
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
shareResource.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"increment").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
shareResource.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"decrement").start();
//-------------------------------------
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
shareResource.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"increment02").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
shareResource.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"decrement02").start();
}
}
//创建资源类
public class LockThreadCommunicationShareResource {
/**
* 初始值
*/
private Integer number = 0;
//创建lock
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
//执行+1
public void increment(){
lock.lock();
try {
while(number!=0){
condition.await();
}
number++;
System.out.println(Thread.currentThread().getName() + "::"+this.number);
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
//执行-1
public void decrement(){
lock.lock();
try {
while(number!=1){
condition.await();
}
number--;
System.out.println(Thread.currentThread().getName() + "::"+this.number);
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) {
// demo1();
LockThreadCommunicationShareResource shareResource
= new LockThreadCommunicationShareResource();
Thread thread0 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
shareResource.increment();
}
}, "lockIncrement");
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
shareResource.increment();
}
}, "lockIncrement01");
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
shareResource.decrement();
}
}, "lockDecrement");
Thread thread3 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
shareResource.decrement();
}
}, "lockIDecrement01");
thread0.start();
thread1.start();
thread2.start();
thread3.start();
}
//创建 资源类
public class CustomThreadCommunityShareResource {
//定义标志位
private Integer flag =1; // 1 thread01 2 thread02 3 thread03
//创建lock锁
private Lock lock = new ReentrantLock();
//创建3个condition
private Condition c1 = lock.newCondition();
private Condition c2 = lock.newCondition();
private Condition c3 = lock.newCondition();
//打印5次,参数为第几轮
public void printFive(Integer loop){
//上锁
lock.lock();
try {
//判断
while(flag!=1){
//等待
c1.await();
}
//打印5次
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+"::"+i+" :轮数: "+loop);
}
//通知
flag = 2;//修改标志位
c2.signal();//通知thread02线程
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放锁
lock.unlock();
}
}
public void printTen(Integer loop){
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;
c3.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printFifteen(Integer loop){
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;
c1.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) {
CustomThreadCommunityShareResource shareResource = new CustomThreadCommunityShareResource();
new Thread(()->{
for (int i = 0; i < 10; i++) {
shareResource.printFive(i);
}
},"AA").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
shareResource.printTen(i);
}
},"BB").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
shareResource.printFifteen(i);
}
},"CC").start();
}
public static void main(String[] args) {
//创建ArrayList
List<String> list = new ArrayList<>();
//并发修改异常
for (int i = 0; i < 100; i++) {
new Thread(()->{
//向集合添加内容
list.add(UUID.randomUUID().toString().toString().substring(0,8));
//从集合中获取内容
System.out.println(list);
},String.valueOf(i)).start();
}
}
public class Phone {
public synchronized void sendSMS() throws InterruptedException {
TimeUnit.SECONDS.sleep(4);
System.out.println("----------sendSMS");
}
public synchronized void sendEmail() throws InterruptedException {
System.out.println("----------sendEmail");
}
public void getHello() {
System.out.println("----------getHello");
}
}
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
// Phone phone2 = new Phone();
new Thread(()->{
try {
phone.sendSMS();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
},"AA").start();
Thread.sleep(100);
new Thread(()->{
try {
phone.sendEmail();
// phone2.sendEmail();
// phone.getHello();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
},"BB").start();
}
/**
* 1.标准访问,先打印短信还是邮件
* ----------sendSMS
* ----------sendEmail
* 2.停4秒在短信方法内,先打印短信还是邮件
* ----------sendSMS
* ----------sendEmail
*
* 对于1和2,synchronized锁的范围是当前对象this,执行时,其它方法只能等待
* 3.新增普通的hello方法,先是打印短信还是邮件
* ----------getHello 与锁无光
* ----------sendSMS
* 4.现在两部手机,先是打印短信还是邮件
* ----------sendEmail
* ----------sendSMS
* 两个对象,synchronized锁的范围是各种对象,先执行Email,SMS在sleep
* 5.两个静态同步方法,1部手机,先是打印短信还是邮件
* ----------sendSMS
* ----------sendEmail
* 6.两个静态同步方法,2部手机,,先是打印短信还是邮件
* ----------sendSMS
* ----------sendEmail
*
* 对于5和6 static synchronized 锁住的是当前类的Class对象
* 7.1个静态同步方法,1个普通同步方法,1部手机,先是打印短信还是邮件
* ----------sendEmail
* ----------sendSMS
* 8.1个静态同步方法,1个普通同步方法,2部手机,先是打印短信还是邮件
* ----------sendEmail
* ----------sendSMS
* 对于7和8是两个不同范围的不同的锁,static是大门的锁,plain是房间的锁
*/
private final ReentrantLock lock = new ReentrantLock(true);
//默认值为flase,非公平锁,将fair置为true此时lock就变成公平锁了
//ReentrantLock类源码
/**
* Creates an instance of {@code ReentrantLock}.
* This is equivalent to using {@code ReentrantLock(false)}.
*/
public ReentrantLock() {
sync = new NonfairSync();
}
/**
* Creates an instance of {@code ReentrantLock} with the
* given fairness policy.
*
* @param fair {@code true} if this lock should use a fair ordering policy
*/
//传入的fair为true创建公平锁,否则使用默认无参构造
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
/**
* Sync object for non-fair locks
*/
//非公平锁进入之后直接执行
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
/**
* Performs lock. Try immediate barge, backing up to normal
* acquire on failure.
*/
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
/**
* Sync object for fair locks
*/
//公平锁进入之后先进行进行礼貌询问
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
final void lock() {
acquire(1);
}
/**
* Fair version of tryAcquire. Don't grant access unless
* recursive call or no waiters or is first.
*/
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
//进行询问
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
//没人,执行操作
setExclusiveOwnerThread(current);
return true;
}
}
//有人,进行排队
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
}
public class ReentrantLockDemo {
public synchronized void add(){
add();
}
//synchronized
public static void main(String[] args) {
new ReentrantLockDemo().add();
}
}
死锁(Deadlock)是指在多线程或多进程的系统中,两个或多个进程或线程由于相互等待对方释放资源而无法继续执行的一种阻塞现象。在死锁状态下,每个进程或线程都在等待其他进程或线程释放资源,导致所有参与的进程或线程都无法继续执行下去。
当以上四个条件同时满足时,就有可能导致死锁的发生。死锁是一种难以调试和解决的问题,因此在设计并发程序时需要特别小心,避免引入可能导致死锁的条件。
解决死锁的方法包括避免死锁、检测死锁和解除死锁。避免死锁的方法通常涉及对资源的动态分配和合理使用,以确保死锁的四个必要条件不同时满足。检测死锁通常涉及周期性地检查系统中是否存在死锁,一旦检测到死锁,可以采取相应的措施解除死锁。解除死锁的方法包括撤销进程、回滚事务或通过抢占资源等。
public class DealLock {
static Object a = new Object();
static Object b = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (a) {
System.out.println(Thread.currentThread().getName() + "持有锁a试图获取锁b");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (b) {
System.out.println(Thread.currentThread().getName() + "获取到锁b");
}
}
}, "A").start();
new Thread(() -> {
synchronized (b) {
System.out.println(Thread.currentThread().getName() + "持有锁b试图获取锁a");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (a) {
System.out.println(Thread.currentThread().getName() + "获取到锁a");
}
}
}, "B").start();
}
}
PS D:\Desktop\JUC_workspace> jps -l
12084 top.ljzstudy.lock.DealLock
18260
20716 org.jetbrains.jps.cmdline.Launcher
5996 jdk.jcmd/sun.tools.jps.Jps
PS D:\Desktop\JUC_workspace> jstack 12084
2024-01-27 14:29:17
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.131-b11 mixed mode):
"DestroyJavaVM" #14 prio=5 os_prio=0 tid=0x0000000002f53800 nid=0x5c2c waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"B" #13 prio=5 os_prio=0 tid=0x0000000024b73000 nid=0x5718 waiting for monitor entry [0x00000000254cf000]
java.lang.Thread.State: BLOCKED (on object monitor)
at top.ljzstudy.lock.DealLock.lambda$main$1(DealLock.java:43)
- waiting to lock <0x0000000740da2ee0> (a java.lang.Object)
- locked <0x0000000740da2ef0> (a java.lang.Object)
at top.ljzstudy.lock.DealLock$$Lambda$2/1831932724.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
"A" #12 prio=5 os_prio=0 tid=0x0000000024b16800 nid=0x5e9c waiting for monitor entry [0x00000000253cf000]
java.lang.Thread.State: BLOCKED (on object monitor)
at top.ljzstudy.lock.DealLock.lambda$main$0(DealLock.java:29)
- waiting to lock <0x0000000740da2ef0> (a java.lang.Object)
- locked <0x0000000740da2ee0> (a java.lang.Object)
at top.ljzstudy.lock.DealLock$$Lambda$1/990368553.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
"Service Thread" #11 daemon prio=9 os_prio=0 tid=0x0000000022f73800 nid=0x2e44 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread3" #10 daemon prio=9 os_prio=2 tid=0x0000000022ece800 nid=0x4810 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x0000000022ece000 nid=0x38d0 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x0000000022eca000 nid=0x58e8 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x0000000022ec5000 nid=0x1060 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x0000000022eb8000 nid=0x2f2c runnable [0x00000000244ce000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
- locked <0x0000000740e2b040> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
- locked <0x0000000740e2b040> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:49)
"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x0000000022e20000 nid=0x5598 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x0000000022e1f000 nid=0x166c runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x000000000304c000 nid=0x1d9c in Object.wait() [0x000000002415f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000740c08ec8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
- locked <0x0000000740c08ec8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)
"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x000000000304b000 nid=0x20e0 in Object.wait() [0x000000002405e000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000740c06b68> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x0000000740c06b68> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"VM Thread" os_prio=2 tid=0x0000000021737000 nid=0x5efc runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000002f69000 nid=0x2240 runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000002f6a800 nid=0x4990 runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000002f6c000 nid=0x50b0 runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000002f6e800 nid=0x37cc runnable
"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x0000000002f70800 nid=0x2d70 runnable
"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x0000000002f72000 nid=0x51c0 runnable
"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x0000000002f75000 nid=0x13d4 runnable
"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x0000000002f76000 nid=0x4e9c runnable
"GC task thread#8 (ParallelGC)" os_prio=0 tid=0x0000000002f77800 nid=0x5ab4 runnable
"GC task thread#9 (ParallelGC)" os_prio=0 tid=0x0000000002f78800 nid=0x5760 runnable
"VM Periodic Task Thread" os_prio=2 tid=0x0000000022fd8000 nid=0x694 waiting on condition
JNI global references: 319
Found one Java-level deadlock:
=============================
"B":
waiting to lock monitor 0x0000000021740be8 (object 0x0000000740da2ee0, a java.lang.Object),
which is held by "A"
"A":
waiting to lock monitor 0x0000000021743528 (object 0x0000000740da2ef0, a java.lang.Object),
which is held by "B"
Java stack information for the threads listed above:
===================================================
"B":
at top.ljzstudy.lock.DealLock.lambda$main$1(DealLock.java:43)
- waiting to lock <0x0000000740da2ee0> (a java.lang.Object)
- locked <0x0000000740da2ef0> (a java.lang.Object)
at top.ljzstudy.lock.DealLock$$Lambda$2/1831932724.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
"A":
at top.ljzstudy.lock.DealLock.lambda$main$0(DealLock.java:29)
- waiting to lock <0x0000000740da2ef0> (a java.lang.Object)
- locked <0x0000000740da2ee0> (a java.lang.Object)
at top.ljzstudy.lock.DealLock$$Lambda$1/990368553.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
Found 1 deadlock.
class MyThread1 implements Runnable{
@Override
public void run() {
}
}
class MyThread2 implements Callable{
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName()+"come in callable");
return 200;
}
}
public class InterfaceComparison {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//使用Runable创建一个线程
new Thread(new MyThread1(),"runable").start();
//使用Callable创建一个线程
//new Thread(new MyThread2(),"callable").start();
//futureTask
FutureTask<Integer> futureTask1 = new FutureTask<>(new MyThread2());
//lamada表达式
FutureTask<Integer> futureTask = new FutureTask<>(()->{
System.out.println(Thread.currentThread().getName()+"come in callable");
return 1024;
});
new Thread(futureTask,"future").start();
while(!futureTask.isDone()){
System.out.println("wait....");
}
System.out.println(futureTask.get());//get方法获取返回值
System.out.println(Thread.currentThread().getName()+"come over");
System.out.println(futureTask.get());
System.out.println(futureTask.get());
new Thread(futureTask,"future").start();
new Thread(futureTask1,"future1").start();
System.out.println(futureTask.get());
System.out.println(futureTask1.get());
System.out.println(Thread.currentThread().getName()+"come over");
//6个同学陆续离开教室之后,班长锁门
public static void main(String[] args) {
//6个同学离开教室之后
for (int i = 1; i <= 6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+" 号同学离开了教室");
},String.valueOf(i)).start();
}
System.out.println(Thread.currentThread().getName()+"班长锁门走人了");
}
//6个同学陆续离开教室之后,班长锁门
public static void main(String[] args) throws InterruptedException {
//6个同学离开教室之后
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 1; i <= 6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+" 号同学离开了教室");
countDownLatch.countDown();//每次让计数器-1
},String.valueOf(i)).start();
}
//countDown不为0,阻塞
countDownLatch.await();
System.out.println(Thread.currentThread().getName()+"班长锁门走人了");
}
//案例:集齐7科龙珠可以转换神龙
//1.创建固定值
private static final Integer NUMBER = 7;
public static void main(String[] args) {
//2.创建CyclicBarrier
CyclicBarrier cyclicBarrier = new CyclicBarrier(NUMBER, () -> {
System.out.println("集齐7科龙珠可以转换神龙");
});
//3.收集龙珠
for (int i = 1; i <= 6; i++) {
//7个线程
new Thread(()->{
System.out.println(Thread.currentThread().getName()+" 星龙被收集到了");
try {
cyclicBarrier.await();
} catch (Exception e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
//6辆汽车,停3个停车位
public static void main(String[] args) {
//创建Semphore,设置许可数量
Semaphore semaphore = new Semaphore(3);
//模拟6辆汽车
for (int i = 1; i <= 6; i++) {
new Thread(()->{
try {
//抢占车位
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+" 抢到了车位");
TimeUnit.SECONDS.sleep(new Random().nextInt(5));
//设置随机停车时间
System.out.println(Thread.currentThread().getName()+" ----离开了车位");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//释放车位
semaphore.release();
}
},String.valueOf(i)).start();
}
}
乐观锁和悲观锁是两种不同的并发控制策略,用于处理多个线程对共享资源的访问
读锁是共享锁,写锁是独占锁,两者都会发生死锁
public class MyCache {
//创建map集合
private Map<String,Object> map = new HashMap<>();
//放数据
public void put(String key,Object value){
System.out.println(Thread.currentThread().getName()+" 正在进行写操作 "+ key);
//暂停一会
try {
TimeUnit.MICROSECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
//放数据
map.put(key,value);
System.out.println(Thread.currentThread().getName()+" 写完了 " + key);
}
//取数据
public Object get(String key){
Object result = null;
System.out.println(Thread.currentThread().getName()+" 正在进行读取操作 "+ key);
//暂停一会
try {
TimeUnit.MICROSECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
//放数据
result = map.get(key);
System.out.println(result!=null?
Thread.currentThread().getName()+" 取完了------- " + key
:Thread.currentThread().getName()+" 没取到--------- " + key);
return result;
}
}
public static void main(String[] args) {
MyCache myCache = new MyCache();
//创建多线程放数据
for (int i = 1; i <=5 ; i++) {
final Integer num = i;
new Thread(()->{
myCache.put(String.valueOf(num),String.valueOf(num));
},String.valueOf(i)).start();
}
//创建多线程取数据
for (int i = 1; i <=5 ; i++) {
final Integer num = i;
new Thread(()->{
myCache.get(String.valueOf(num));
},String.valueOf(i)).start();
}
}
public class MyCache {
//创建map集合
private Map<String,Object> map = new HashMap<>();
//创建读写锁对象
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
//放数据
public void put(String key,Object value){
//写操作,加写锁
readWriteLock.writeLock().lock();
System.out.println(Thread.currentThread().getName()+" 正在进行写操作 "+ key);
//暂停一会
try {
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 Object get(String key){
//读取数据,加读锁
readWriteLock.readLock().lock();
Object result = null;
try {
System.out.println(Thread.currentThread().getName()+" 正在进行读取操作 "+ key);
//暂停一会
TimeUnit.MICROSECONDS.sleep(300);
//放数据
result = map.get(key);
System.out.println(result!=null?
Thread.currentThread().getName()+" 取完了------- " + key
:Thread.currentThread().getName()+" 没取到--------- " + key);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//释放读锁
readWriteLock.readLock().unlock();
}
return result;
}
}
一个资源可以被多个读线程访问,或者可以被一个写线程访问,但是不能够同时存在读写线程 读写互斥,读读共享
将写入锁将为读锁
//写锁降级为读锁
public static void main(String[] args) {
//可重入读写锁对象
ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
//创建读写锁
ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
//演示锁降级
writeLock.lock(); //获取写锁
System.out.println("get write lock");
readLock.lock(); //获取读锁
System.out.println("get read lock");
writeLock.unlock(); //释放写锁
readLock.unlock(); //释放读锁
}
在concurrent包发布以前,在多线程环境下,我们每个程序员都必须去自己控制这些细节,尤其还要兼顾效率和线程安全,而这会给我们的程序带来不小的复杂度。使用后我们不需要关心什么时候需要阻塞线程,什么时候需要唤醒线程,因为这一切BlockingQueue都给你一手包办了
public static void main(String[] args) throws InterruptedException {
//创建阻塞对列
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue(3);
//group add()
// System.out.println(blockingQueue.add("a"));
// System.out.println(blockingQueue.add("b"));
// System.out.println(blockingQueue.add("c"));
System.out.println(blockingQueue.element());
System.out.println(blockingQueue.add("d"));
// System.out.println(blockingQueue.remove());
// System.out.println(blockingQueue.remove());
// System.out.println(blockingQueue.remove());
// System.out.println(blockingQueue.remove());
//group offer(e)
// System.out.println(blockingQueue.offer("a"));
// System.out.println(blockingQueue.offer("b"));
// System.out.println(blockingQueue.offer("c"));
System.out.println(blockingQueue.offer("d"));
// System.out.println(blockingQueue.poll());
// System.out.println(blockingQueue.poll());
// System.out.println(blockingQueue.peek());
// System.out.println(blockingQueue.poll());
//group put(e)
// blockingQueue.put("a");
// System.out.println(blockingQueue.take());
// blockingQueue.put("b");
// blockingQueue.put("c");
// System.out.println(blockingQueue.take());
// blockingQueue.put("d");
// System.out.println(blockingQueue.take());
// System.out.println(blockingQueue.take());
//group offer-time_out
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("c"));
System.out.println(blockingQueue.offer("d",3L, TimeUnit.SECONDS));
}
Executors.newFixedThreadPool(int)
public static void main(String[] args) {
//一池n线程
//场景描述:银行5个窗口,处理10个顾客的业务
ExecutorService threadPool = Executors.newFixedThreadPool(5);
try {
for (int i = 1; i <= 10; i++) {
//执行
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName()+" 办理业务");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭资源
threadPool.shutdown();
}
}
Executors.newSingleThreadExecutor()
ExecutorService threadPool = Executors.newSingleThreadExecutor();
Executors.newCachedThreadPool()
ExecutorService threadPool = Executors.newCachedThreadPool();
public ThreadPoolExecutor(int corePoolSize, //常驻线程线程数量(核心)
int maximumPoolSize, //最大线程数量
long keepAliveTime, //存活时间
TimeUnit unit, //存活时间单位
BlockingQueue<Runnable> workQueue, //阻塞队列
ThreadFactory threadFactory, //线程工厂
RejectedExecutionHandler handler //拒绝策略
) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
//自定义线程池创建
public static void main(String[] args) {
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
2,
5,
2L,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
try {
for (int i = 1; i <= 10; i++) {
//执行
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName()+" 办理业务");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭资源
threadPool.shutdown();
}
}
public class MyTask extends RecursiveTask<Integer> {
//拆分的差值不能超过10
private static final Integer DIFFERENCE = 10;
private Integer begin; //拆分起始值
private Integer end; //拆分结束值
private int result; //结果值
//创建有参构造
public MyTask(Integer begin, Integer end) {
this.begin = begin;
this.end = end;
}
//拆分与合并过程
@Override
protected Integer compute() {
//判断相加的两个值是否大于10
if ((end-begin)<=DIFFERENCE) {
//相加
for (int i = begin; i <=end; i++) {
result += i;
}
}else{
//进一步拆分
int middle = (begin+end)/2;
//拆分左边
MyTask myTask01 = new MyTask(begin, middle);
//拆分右边
MyTask myTask02 = new MyTask(middle+1, end);
//执行拆分
myTask01.fork();
myTask02.fork();
//合并结果
result = myTask01.join()+ myTask02.join();
}
return result;
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
//创建MyTask对象
MyTask myTask = new MyTask(0, 100);
//创建分支池对象
ForkJoinPool forkJoinPool = new ForkJoinPool();
ForkJoinTask<Integer> forkJoinTask = forkJoinPool.submit(myTask);
//获取合并结果
Integer result = forkJoinTask.get();
System.out.println(result);
forkJoinPool.shutdown();
}
private static void nonReturnValue() throws InterruptedException, ExecutionException {
//异步调用没有返回值
CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(()->{
System.out.println(Thread.currentThread().getName()+" completableFuture1");
});
completableFuture.get();
}
private static void returnValue() {
//异步调用有返回值
CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName() + " completableFuture02");
int i = 1/0; //模拟异常
return 1024;
});
completableFuture.whenComplete((t,u)->{
System.out.println("t = " + t);
//u为异常信息
System.out.println("u = " + u);
});
}