首页>>后端>>java->高频多线程高并发JUC编程(二)

高频多线程高并发JUC编程(二)

时间:2023-12-02 本站 点击:0

接上一篇文章:高频多线程高并发JUC编程(一)

5、8锁现象

1-2锁

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test1*@Author:张晟睿*@Date:2021/9/521:18*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest1*@Description*@Author张晟睿*@Date2021/9/5**//**8锁,就是关于锁的8个问题*1、标准情况下,两个线程先打印发短信还是打电话?发短信*2、sendSms方法延迟4s,两个线程先打印发短信还是打电话?发短信**/publicclassTest1{publicstaticvoidmain(String[]args){Phonephone=newPhone();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone.call();},"B").start();}}classPhone{//synchronized锁的对象是方法的调用者!//两个方法用的都是phone对象的锁!//谁先拿到谁执行!publicsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicsynchronizedvoidcall(){System.out.println("打电话");}}

3-4锁

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test2*@Author:张晟睿*@Date:2021/9/521:26*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest2*@Description*@Author张晟睿*@Date2021/9/5**///3、增加一个普通方法后!发短信还是Hello,发短信hello//4、两个对象,两个同步方法,发短信还是打电话打电话publicclassTest2{publicstaticvoidmain(String[]args){//两个对象,两把锁Phone2phone=newPhone2();Phone2phone2=newPhone2();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}classPhone2{//synchronized锁的对象是方法的调用者!publicsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicsynchronizedvoidcall(){System.out.println("打电话");}//这里没有锁!bubu不是同步方法,不受锁的影响publicvoidhello(){System.out.println("hello");}}

5-6锁

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test3*@Author:张晟睿*@Date:2021/9/612:35*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest3*@Description*@Author张晟睿*@Date2021/9/6**//**5、增加两个静态同步方法,只有一个对象,先打印发短信还是打电话?发短信*6、两个对象!增加两个静态同步方法,只有一个对象,先打印发短信还是打电话发短信**/publicclassTest3{publicstaticvoidmain(String[]args){//两个对象,两个调用者,两把锁!//两个对象的class类模板只有一个,static,锁的是ClassPhone3phone=newPhone3();Phone3phone2=newPhone3();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}//Phone3唯一的一个Class对象classPhone3{//synchronized锁的对象是方法的调用者!//static静态方法//类一加载就有了!Class模板锁的是ClasspublicstaticsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicstaticsynchronizedvoidcall(){System.out.println("打电话");}}

7-8锁

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test4*@Author:张晟睿*@Date:2021/9/613:07*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest4*@Description*@Author张晟睿*@Date2021/9/6**//**1个静态同步方法,1个同步方法,1个对象先打印发短信还是打电话?打电话*1个静态同步方法,1个同步方法,2个对象先打印发短信还是打电话?发短信**/publicclassTest4{publicstaticvoidmain(String[]args){//两个对象,两个调用者,两把锁!//两个对象的class类模板只有一个,static,锁的是ClassPhone4phone=newPhone4();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone.call();},"B").start();}}//Phone4唯一的一个Class对象classPhone4{//synchronized锁的对象是方法的调用者!//锁的是Class类模板publicstaticsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}//锁的是调用者publicsynchronizedvoidcall(){System.out.println("打电话");}}

6、集合不安全

1、ArrayList集合不安全

packagecom;/***@ProjectName:Juc*@Package:com*@ClassName:unsafe*@Author:张晟睿*@Date:2021/9/619:37*@Version:1.0*/importjava.util.*;importjava.util.concurrent.CopyOnWriteArrayList;/***@ClassNameunsafe*@Description*@Author张晟睿*@Date2021/9/6**/publicclassunsafe{publicstaticvoidmain(String[]args){//高并发下的ArrayList真的安全么?/***解决方法*1、List<String>list=newVector<String>();*2、List<String>list=Collections.synchronizedList(newArrayList<>());*3、List<String>list=newCopyOnWriteArrayList<>();**/List<String>list=newCopyOnWriteArrayList<>();//启动10个多线程for(inti=1;i<10;i++){newThread(()->{list.add(UUID.randomUUID().toString().substring(0,5));System.out.println(list);},String.valueOf(i)).start();}}}

CopyOnWriteArrayList源码分析

2、Set不安全

packagecom.zmz.unsafe;/***@ProjectName:Juc*@Package:com.zmz.unsafe*@ClassName:SetSafe*@Author:张晟睿*@Date:2021/9/621:20*@Version:1.0*/importjava.util.Collections;importjava.util.HashSet;importjava.util.Set;importjava.util.UUID;importjava.util.concurrent.CopyOnWriteArraySet;/***@ClassNameSetSafe*@Description*@Author张晟睿*@Date2021/9/6**/publicclassSetSafe{publicstaticvoidmain(String[]args){//Set<String>set=newHashSet<>();//Set<String>set=Collections.synchronizedSet(newHashSet<>());Set<String>set=newCopyOnWriteArraySet<>();for(inti=1;i<60;i++){newThread(()->{set.add(UUID.randomUUID().toString().substring(0,5));System.out.println(set);},String.valueOf(i)).start();}}}

HashSet源码

publicHashSet(){map=newHashMap<>();}//HashSet本质就是Map集合publicbooleanadd(Ee){returnmap.put(e,PRESENT)==null;}privatestaticfinalObjectPRESENT=newObject();//不变的值

3、HashMap不安全

packagecom.zmz.unsafe;/***@ProjectName:Juc*@Package:com.zmz.unsafe*@ClassName:MapSafe*@Author:张晟睿*@Date:2021/9/621:27*@Version:1.0*/importjava.util.Collections;importjava.util.HashMap;importjava.util.Map;importjava.util.UUID;importjava.util.concurrent.ConcurrentHashMap;/***@ClassNameMapSafe*@Description*@Author张晟睿*@Date2021/9/6**/publicclassMapSafe{publicstaticvoidmain(String[]args){//Map<String,String>map=newHashMap<>();//Map<String,Object>map=Collections.synchronizedMap(newHashMap<>());Map<String,Object>map=newConcurrentHashMap<>();for(inti=1;i<=30;i++){newThread(()->{map.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0,5));System.out.println(map);},String.valueOf(i)).start();}}}

7、Callable

可以有返回值

可以抛出异常

方法不同,run()/call()

callable源码

代码测试

packagecom.zmz.callable;/***@ProjectName:Juc*@Package:com.zmz.callable*@ClassName:CallableTest*@Author:张晟睿*@Date:2021/10/316:52*@Version:1.0*/importcom.sun.org.apache.bcel.internal.generic.NEW;importjava.util.concurrent.Callable;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.FutureTask;/***@ClassNameCallableTest*@Description*@Author张晟睿*@Date2021/10/3**/publicclassCallableTest{publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{//newThread(newRunnable()).start();//newThread(newFutureTask<V>()).start();//newThread(newFutureTask<V>(Callable)).start();newThread().start();MyThreadmyThread=newMyThread();FutureTaskfutureTask=newFutureTask(myThread);//适配类newThread(futureTask,"A").start();newThread(futureTask,"B").start();//结果存在缓存提交效率Integero=(Integer)futureTask.get();//获取返回的结果//这个get方法可以会产生阻塞!解决办法放到最后一行或者异步通信System.out.println(o);}}classMyThreadimplementsCallable<Integer>{@OverridepublicIntegercall()throwsException{System.out.println("call()方法");//耗时操作return1024;}}/*1、有缓存2、结果可能会等待,阻塞*/

8、常用的辅助类

1) CountDownLatch—减法计数器

packagecom.zmz.assist;/***@ProjectName:Juc*@Package:com.zmz.assist*@ClassName:CountDownLatchDemo*@Author:张晟睿*@Date:2021/10/318:00*@Version:1.0*/importjava.util.concurrent.CountDownLatch;/***@ClassNameCountDownLatchDemo*@Description*@Author张晟睿*@Date2021/10/3**/publicclassCountDownLatchDemo{publicstaticvoidmain(String[]args)throwsInterruptedException{CountDownLatchcount=newCountDownLatch(10);for(inti=1;i<=10;i++){newThread(()->{System.out.println(Thread.currentThread().getName()+"Goout");count.countDown();//数量-1},String.valueOf(i)).start();}count.await();//等计数器归零,然后再往下执行System.out.println("CloseDoor");}}

原理:

count.countDown();//数量-1

count.await();//等待计数器归零。然后再向下执行

每次有线程用countDown()数量-1,如果计算器变为0了,然后count.await()就被唤醒,继续下面的执行!

2) CyclicBarrier—加法计数器

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test2*@Author:张晟睿*@Date:2021/9/521:26*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest2*@Description*@Author张晟睿*@Date2021/9/5**///3、增加一个普通方法后!发短信还是Hello,发短信hello//4、两个对象,两个同步方法,发短信还是打电话打电话publicclassTest2{publicstaticvoidmain(String[]args){//两个对象,两把锁Phone2phone=newPhone2();Phone2phone2=newPhone2();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}classPhone2{//synchronized锁的对象是方法的调用者!publicsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicsynchronizedvoidcall(){System.out.println("打电话");}//这里没有锁!bubu不是同步方法,不受锁的影响publicvoidhello(){System.out.println("hello");}}0

3) Semaphore

Semaphore:信号量,很多时候用来处理高并发。

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test2*@Author:张晟睿*@Date:2021/9/521:26*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest2*@Description*@Author张晟睿*@Date2021/9/5**///3、增加一个普通方法后!发短信还是Hello,发短信hello//4、两个对象,两个同步方法,发短信还是打电话打电话publicclassTest2{publicstaticvoidmain(String[]args){//两个对象,两把锁Phone2phone=newPhone2();Phone2phone2=newPhone2();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}classPhone2{//synchronized锁的对象是方法的调用者!publicsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicsynchronizedvoidcall(){System.out.println("打电话");}//这里没有锁!bubu不是同步方法,不受锁的影响publicvoidhello(){System.out.println("hello");}}1

原理:

acquire():获得,假设已经满了组需要等待,直到被释放为止

release():释放,会将当前的信号量释放+1,然后唤醒等待的线程!

作用:多个共享的资源互斥使用!并发限流控制最大的线程数量!

9、读写锁ReadwriteLock

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test2*@Author:张晟睿*@Date:2021/9/521:26*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest2*@Description*@Author张晟睿*@Date2021/9/5**///3、增加一个普通方法后!发短信还是Hello,发短信hello//4、两个对象,两个同步方法,发短信还是打电话打电话publicclassTest2{publicstaticvoidmain(String[]args){//两个对象,两把锁Phone2phone=newPhone2();Phone2phone2=newPhone2();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}classPhone2{//synchronized锁的对象是方法的调用者!publicsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicsynchronizedvoidcall(){System.out.println("打电话");}//这里没有锁!bubu不是同步方法,不受锁的影响publicvoidhello(){System.out.println("hello");}}2

我们可以看到出现了严重的插队问题!该如何去解决囊?我们使用读写锁来解决插队的问题。

修改后的操作

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test2*@Author:张晟睿*@Date:2021/9/521:26*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest2*@Description*@Author张晟睿*@Date2021/9/5**///3、增加一个普通方法后!发短信还是Hello,发短信hello//4、两个对象,两个同步方法,发短信还是打电话打电话publicclassTest2{publicstaticvoidmain(String[]args){//两个对象,两把锁Phone2phone=newPhone2();Phone2phone2=newPhone2();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}classPhone2{//synchronized锁的对象是方法的调用者!publicsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicsynchronizedvoidcall(){System.out.println("打电话");}//这里没有锁!bubu不是同步方法,不受锁的影响publicvoidhello(){System.out.println("hello");}}3

我们可以看到输出的结果在写入的时候有序的进行,读操作的时候可以无序的进行,可以看到已经到达我们预期的效果?

10、堵塞队列

堵塞

什么情况下我们使用阻塞队列:多线程并发处理,线程池!

10.1 学会使用队列

添加、移除元素,现在有四组API

1) 四组API

方法抛出异常不会抛出异常,有返回值阻塞等待超时等待添加add()offer()put()offer(E e, long timeout, TimeUnit unit)移除remove()poll()take()poll(long timeout, TimeUnit unit)判断首部element()peek()--
packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test2*@Author:张晟睿*@Date:2021/9/521:26*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest2*@Description*@Author张晟睿*@Date2021/9/5**///3、增加一个普通方法后!发短信还是Hello,发短信hello//4、两个对象,两个同步方法,发短信还是打电话打电话publicclassTest2{publicstaticvoidmain(String[]args){//两个对象,两把锁Phone2phone=newPhone2();Phone2phone2=newPhone2();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}classPhone2{//synchronized锁的对象是方法的调用者!publicsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicsynchronizedvoidcall(){System.out.println("打电话");}//这里没有锁!bubu不是同步方法,不受锁的影响publicvoidhello(){System.out.println("hello");}}4

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test2*@Author:张晟睿*@Date:2021/9/521:26*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest2*@Description*@Author张晟睿*@Date2021/9/5**///3、增加一个普通方法后!发短信还是Hello,发短信hello//4、两个对象,两个同步方法,发短信还是打电话打电话publicclassTest2{publicstaticvoidmain(String[]args){//两个对象,两把锁Phone2phone=newPhone2();Phone2phone2=newPhone2();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}classPhone2{//synchronized锁的对象是方法的调用者!publicsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicsynchronizedvoidcall(){System.out.println("打电话");}//这里没有锁!bubu不是同步方法,不受锁的影响publicvoidhello(){System.out.println("hello");}}5
packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test2*@Author:张晟睿*@Date:2021/9/521:26*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest2*@Description*@Author张晟睿*@Date2021/9/5**///3、增加一个普通方法后!发短信还是Hello,发短信hello//4、两个对象,两个同步方法,发短信还是打电话打电话publicclassTest2{publicstaticvoidmain(String[]args){//两个对象,两把锁Phone2phone=newPhone2();Phone2phone2=newPhone2();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}classPhone2{//synchronized锁的对象是方法的调用者!publicsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicsynchronizedvoidcall(){System.out.println("打电话");}//这里没有锁!bubu不是同步方法,不受锁的影响publicvoidhello(){System.out.println("hello");}}6
packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test2*@Author:张晟睿*@Date:2021/9/521:26*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest2*@Description*@Author张晟睿*@Date2021/9/5**///3、增加一个普通方法后!发短信还是Hello,发短信hello//4、两个对象,两个同步方法,发短信还是打电话打电话publicclassTest2{publicstaticvoidmain(String[]args){//两个对象,两把锁Phone2phone=newPhone2();Phone2phone2=newPhone2();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}classPhone2{//synchronized锁的对象是方法的调用者!publicsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicsynchronizedvoidcall(){System.out.println("打电话");}//这里没有锁!bubu不是同步方法,不受锁的影响publicvoidhello(){System.out.println("hello");}}7

2) SynchronizedQueue 同步队列

没有容量,进去一个元素,必须等待取出来之后,才能再往里面放一个元素

put take

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test2*@Author:张晟睿*@Date:2021/9/521:26*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest2*@Description*@Author张晟睿*@Date2021/9/5**///3、增加一个普通方法后!发短信还是Hello,发短信hello//4、两个对象,两个同步方法,发短信还是打电话打电话publicclassTest2{publicstaticvoidmain(String[]args){//两个对象,两把锁Phone2phone=newPhone2();Phone2phone2=newPhone2();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}classPhone2{//synchronized锁的对象是方法的调用者!publicsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicsynchronizedvoidcall(){System.out.println("打电话");}//这里没有锁!bubu不是同步方法,不受锁的影响publicvoidhello(){System.out.println("hello");}}8

11、线程池

线程池有三大方法,七大参数,四种拒绝策略

程序的运行,本质: 占用系统的资源 ! 优化CPU资源的使用 ===>池化技术

线程池, 连接池, 内存池, 对象池///…

池化技术: 实现准备好一些资源, 有人要用,就来我这里拿,用完之后还给我

1) 线程池的好处:

降低资源消耗

提高响应速度

方便管理

线程复用,可以控制最大并发数,管理线程

2) 线程池: 三大方法

ExecutorService service = Executors.newSingleThreadExecutor();//单个线程

ExecutorService service = Executors.newFixedThreadPool(5);//创建一个固定的线程池的大小

ExecutorService service = Executors.newCachedThreadPool();//可伸缩的,

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test2*@Author:张晟睿*@Date:2021/9/521:26*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest2*@Description*@Author张晟睿*@Date2021/9/5**///3、增加一个普通方法后!发短信还是Hello,发短信hello//4、两个对象,两个同步方法,发短信还是打电话打电话publicclassTest2{publicstaticvoidmain(String[]args){//两个对象,两把锁Phone2phone=newPhone2();Phone2phone2=newPhone2();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}classPhone2{//synchronized锁的对象是方法的调用者!publicsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicsynchronizedvoidcall(){System.out.println("打电话");}//这里没有锁!bubu不是同步方法,不受锁的影响publicvoidhello(){System.out.println("hello");}}9

3) 七大参数

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test3*@Author:张晟睿*@Date:2021/9/612:35*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest3*@Description*@Author张晟睿*@Date2021/9/6**//**5、增加两个静态同步方法,只有一个对象,先打印发短信还是打电话?发短信*6、两个对象!增加两个静态同步方法,只有一个对象,先打印发短信还是打电话发短信**/publicclassTest3{publicstaticvoidmain(String[]args){//两个对象,两个调用者,两把锁!//两个对象的class类模板只有一个,static,锁的是ClassPhone3phone=newPhone3();Phone3phone2=newPhone3();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}//Phone3唯一的一个Class对象classPhone3{//synchronized锁的对象是方法的调用者!//static静态方法//类一加载就有了!Class模板锁的是ClasspublicstaticsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicstaticsynchronizedvoidcall(){System.out.println("打电话");}}0

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test3*@Author:张晟睿*@Date:2021/9/612:35*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest3*@Description*@Author张晟睿*@Date2021/9/6**//**5、增加两个静态同步方法,只有一个对象,先打印发短信还是打电话?发短信*6、两个对象!增加两个静态同步方法,只有一个对象,先打印发短信还是打电话发短信**/publicclassTest3{publicstaticvoidmain(String[]args){//两个对象,两个调用者,两把锁!//两个对象的class类模板只有一个,static,锁的是ClassPhone3phone=newPhone3();Phone3phone2=newPhone3();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}//Phone3唯一的一个Class对象classPhone3{//synchronized锁的对象是方法的调用者!//static静态方法//类一加载就有了!Class模板锁的是ClasspublicstaticsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicstaticsynchronizedvoidcall(){System.out.println("打电话");}}1

4) 拒绝策略

new ThreadPoolExecutor.AbortPolicy() 超出最大处理线程抛出异常

new ThreadPoolExecutor.CallerRunsPolicy() 从哪个线程创建就由那个线程执行

new ThreadPoolExecutor.DiscardPolicy() 队列满了不会抛出异常

new ThreadPoolExecutor.DiscardOldestPolicy() 尝试去和第一个竞争,也不会抛出异常

12、四大函数式接口

新时代的程序员?‍?:lambda表达式、链式编程、函数式接口、Stream流式计算

1) Function函数型接口

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test3*@Author:张晟睿*@Date:2021/9/612:35*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest3*@Description*@Author张晟睿*@Date2021/9/6**//**5、增加两个静态同步方法,只有一个对象,先打印发短信还是打电话?发短信*6、两个对象!增加两个静态同步方法,只有一个对象,先打印发短信还是打电话发短信**/publicclassTest3{publicstaticvoidmain(String[]args){//两个对象,两个调用者,两把锁!//两个对象的class类模板只有一个,static,锁的是ClassPhone3phone=newPhone3();Phone3phone2=newPhone3();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}//Phone3唯一的一个Class对象classPhone3{//synchronized锁的对象是方法的调用者!//static静态方法//类一加载就有了!Class模板锁的是ClasspublicstaticsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicstaticsynchronizedvoidcall(){System.out.println("打电话");}}2

2) Predicate 断定型接口

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test3*@Author:张晟睿*@Date:2021/9/612:35*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest3*@Description*@Author张晟睿*@Date2021/9/6**//**5、增加两个静态同步方法,只有一个对象,先打印发短信还是打电话?发短信*6、两个对象!增加两个静态同步方法,只有一个对象,先打印发短信还是打电话发短信**/publicclassTest3{publicstaticvoidmain(String[]args){//两个对象,两个调用者,两把锁!//两个对象的class类模板只有一个,static,锁的是ClassPhone3phone=newPhone3();Phone3phone2=newPhone3();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}//Phone3唯一的一个Class对象classPhone3{//synchronized锁的对象是方法的调用者!//static静态方法//类一加载就有了!Class模板锁的是ClasspublicstaticsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicstaticsynchronizedvoidcall(){System.out.println("打电话");}}3

3) Suppier 供给型接口

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test3*@Author:张晟睿*@Date:2021/9/612:35*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest3*@Description*@Author张晟睿*@Date2021/9/6**//**5、增加两个静态同步方法,只有一个对象,先打印发短信还是打电话?发短信*6、两个对象!增加两个静态同步方法,只有一个对象,先打印发短信还是打电话发短信**/publicclassTest3{publicstaticvoidmain(String[]args){//两个对象,两个调用者,两把锁!//两个对象的class类模板只有一个,static,锁的是ClassPhone3phone=newPhone3();Phone3phone2=newPhone3();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}//Phone3唯一的一个Class对象classPhone3{//synchronized锁的对象是方法的调用者!//static静态方法//类一加载就有了!Class模板锁的是ClasspublicstaticsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicstaticsynchronizedvoidcall(){System.out.println("打电话");}}4

4) Consummer 消费型接口

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test3*@Author:张晟睿*@Date:2021/9/612:35*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest3*@Description*@Author张晟睿*@Date2021/9/6**//**5、增加两个静态同步方法,只有一个对象,先打印发短信还是打电话?发短信*6、两个对象!增加两个静态同步方法,只有一个对象,先打印发短信还是打电话发短信**/publicclassTest3{publicstaticvoidmain(String[]args){//两个对象,两个调用者,两把锁!//两个对象的class类模板只有一个,static,锁的是ClassPhone3phone=newPhone3();Phone3phone2=newPhone3();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}//Phone3唯一的一个Class对象classPhone3{//synchronized锁的对象是方法的调用者!//static静态方法//类一加载就有了!Class模板锁的是ClasspublicstaticsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicstaticsynchronizedvoidcall(){System.out.println("打电话");}}5

13、Stream 流式计算

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test3*@Author:张晟睿*@Date:2021/9/612:35*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest3*@Description*@Author张晟睿*@Date2021/9/6**//**5、增加两个静态同步方法,只有一个对象,先打印发短信还是打电话?发短信*6、两个对象!增加两个静态同步方法,只有一个对象,先打印发短信还是打电话发短信**/publicclassTest3{publicstaticvoidmain(String[]args){//两个对象,两个调用者,两把锁!//两个对象的class类模板只有一个,static,锁的是ClassPhone3phone=newPhone3();Phone3phone2=newPhone3();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}//Phone3唯一的一个Class对象classPhone3{//synchronized锁的对象是方法的调用者!//static静态方法//类一加载就有了!Class模板锁的是ClasspublicstaticsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicstaticsynchronizedvoidcall(){System.out.println("打电话");}}6
packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test3*@Author:张晟睿*@Date:2021/9/612:35*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest3*@Description*@Author张晟睿*@Date2021/9/6**//**5、增加两个静态同步方法,只有一个对象,先打印发短信还是打电话?发短信*6、两个对象!增加两个静态同步方法,只有一个对象,先打印发短信还是打电话发短信**/publicclassTest3{publicstaticvoidmain(String[]args){//两个对象,两个调用者,两把锁!//两个对象的class类模板只有一个,static,锁的是ClassPhone3phone=newPhone3();Phone3phone2=newPhone3();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}//Phone3唯一的一个Class对象classPhone3{//synchronized锁的对象是方法的调用者!//static静态方法//类一加载就有了!Class模板锁的是ClasspublicstaticsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicstaticsynchronizedvoidcall(){System.out.println("打电话");}}7

14、ForkJoin—多线并发处理框架

什么是ForkJoin?

ava.util.concurrent.ForkJoinPool由Java大师Doug Lea主持编写,它可以将一个大的任务拆分成多个子任务进行并行处理,最后将子任务结果合并成最后的计算结果,并进行输出。本文中对Fork/Join框架的讲解,基于JDK1.8+中的Fork/Join框架实现,参考的Fork/Join框架主要源代码也基于JDK1.8+。

这几篇文章将试图解释Fork/Join框架的知识点,以便对自己、对各位读者在并发程序的设计思路上进行一些启发。文章将首先讲解Fork/Join框架的基本使用,以及其中需要注意的使用要点;接着使用Fork/Join框架解决一些实际问题;最后再讲解Fork/Join框架的工作原理。

1)ForkJoin 特点: 工作窃取!

2)如果使用ForkJoin

第一步,通过ForkJoinPool来执行

第二步,计算任务 execute(ForkJoinTask<?> task)

第三步,计算类要去继承ForkJoinTask

ForkJoin 的计算类

ForkJoinComputer.java

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test3*@Author:张晟睿*@Date:2021/9/612:35*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest3*@Description*@Author张晟睿*@Date2021/9/6**//**5、增加两个静态同步方法,只有一个对象,先打印发短信还是打电话?发短信*6、两个对象!增加两个静态同步方法,只有一个对象,先打印发短信还是打电话发短信**/publicclassTest3{publicstaticvoidmain(String[]args){//两个对象,两个调用者,两把锁!//两个对象的class类模板只有一个,static,锁的是ClassPhone3phone=newPhone3();Phone3phone2=newPhone3();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}//Phone3唯一的一个Class对象classPhone3{//synchronized锁的对象是方法的调用者!//static静态方法//类一加载就有了!Class模板锁的是ClasspublicstaticsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicstaticsynchronizedvoidcall(){System.out.println("打电话");}}8

测试类 ForkJoinTest.java

packagecom.zmz.lock8;/***@ProjectName:Juc*@Package:com.zmz.lock8*@ClassName:Test3*@Author:张晟睿*@Date:2021/9/612:35*@Version:1.0*/importjava.util.concurrent.TimeUnit;/***@ClassNameTest3*@Description*@Author张晟睿*@Date2021/9/6**//**5、增加两个静态同步方法,只有一个对象,先打印发短信还是打电话?发短信*6、两个对象!增加两个静态同步方法,只有一个对象,先打印发短信还是打电话发短信**/publicclassTest3{publicstaticvoidmain(String[]args){//两个对象,两个调用者,两把锁!//两个对象的class类模板只有一个,static,锁的是ClassPhone3phone=newPhone3();Phone3phone2=newPhone3();//锁存在newThread(()->{phone.sendSms();},"A").start();try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}newThread(()->{phone2.call();},"B").start();}}//Phone3唯一的一个Class对象classPhone3{//synchronized锁的对象是方法的调用者!//static静态方法//类一加载就有了!Class模板锁的是ClasspublicstaticsynchronizedvoidsendSms(){try{TimeUnit.SECONDS.sleep(4);}catch(InterruptedExceptione){e.printStackTrace();}System.out.println("发短信");}publicstaticsynchronizedvoidcall(){System.out.println("打电话");}}9

分析一下高级程序猿的处理:

.parallel().reduce(0, Long::sum)使用一个并行流去计算整个计算,提高效率。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/java/10494.html