-
2020-04-12 23:34:57
1,相关文章推荐
2,直接源码
package com.wayne.latchPattern; import java.sql.Time; import java.util.concurrent.TimeUnit; public abstract class Latch { protected int limit; public Latch(int limit){ this.limit = limit; } public abstract void await() throws InterruptedException; public abstract void await(TimeUnit timeUnit,long time) throws InterruptedException, WaitTimeoutException; public abstract void countdown(); public abstract int getUnArrived(); }
package com.wayne.latchPattern; import java.util.concurrent.TimeUnit; public class CountDownLatch extends Latch { public CountDownLatch(int limit){ super(limit); } @Override public void await() throws InterruptedException { synchronized (this){ while (limit >0) { this.wait(); } } } @Override public void await(TimeUnit timeUnit, long time) throws InterruptedException,WaitTimeoutException { if(time <= 0 ){ throw new IllegalArgumentException("time is invaild."); } long remainingNanos = timeUnit.toNanos(time); final long endNanos = System.nanoTime() + remainingNanos; synchronized (this){ while (limit > 0){ if(TimeUnit.NANOSECONDS.toMillis(remainingNanos)<= 0){ throw new WaitTimeoutException("The wait time over specify time."); } this.wait(TimeUnit.NANOSECONDS.toMillis(remainingNanos)); remainingNanos = endNanos - System.nanoTime(); } } } @Override public void countdown() { synchronized (this){ if(limit <= 0){ throw new IllegalStateException(" all arrived"); } limit--; this.notifyAll(); } } @Override public int getUnArrived() { synchronized (this){ return limit; } } }
package com.wayne.latchPattern; import org.omg.CORBA.TIMEOUT; import java.util.Random; import java.util.concurrent.TimeUnit; public class ProgrammerTravel extends Thread { private final Latch latch; private final String programmer; private final String transport; public ProgrammerTravel(Latch latch,String programmer,String transport){ this.latch = latch; this.programmer = programmer; this.transport = transport; } @Override public void run() { try{ System.out.println(programmer+" start to move with "+ transport); TimeUnit.SECONDS.sleep(new Random(System.currentTimeMillis()).nextInt(10)); } catch (Exception e){ e.printStackTrace(); } System.out.println(programmer+" with "+transport+ " has arrived!"); latch.countdown(); } }
package com.wayne.latchPattern; public class WaitTimeoutException extends Exception { public WaitTimeoutException(String message){ super(message); } }
package com.wayne.latchPattern; import java.util.concurrent.TimeUnit; public class LatchPatternTest { public static void main(String[] args) throws InterruptedException, WaitTimeoutException { Latch latch = new CountDownLatch(4); new ProgrammerTravel(latch,"Wayne","Bicycle").start(); new ProgrammerTravel(latch,"Bruce","Bus").start(); new ProgrammerTravel(latch,"Batman","Car").start(); new ProgrammerTravel(latch,"IronMan","Flight").start(); latch.await(TimeUnit.SECONDS,5); System.out.println("All arrived,let's start!"); } }
更多相关内容 -
Java多线程并发系列之闭锁(Latch)和栅栏(CyclicBarrier)
2021-02-26 09:33:09JAVA并发包中有三个类用于同步一批线程的行为,分别是...1. 闭锁(Latch)闭锁(Latch) —— 确保多个线程在完成各自事务后,才会打开继续执行后面的内容,否则一直等待。计数器闭锁(CountDownLatch) —— 是JDK5+ 里面...JAVA并发包中有三个类用于同步一批线程的行为,分别是闭锁(Latch),信号灯(Semaphore)和栅栏(CyclicBarrier)。本贴主要说明闭锁(Latch)和栅栏(CyclicBarrier)。
1. 闭锁(Latch)
闭锁(Latch) —— 确保多个线程在完成各自事务后,才会打开继续执行后面的内容,否则一直等待。
计数器闭锁(CountDownLatch) —— 是JDK5+ 里面闭锁的一个实现,允许一个或多个线程等待某个事件的发生。CountDownLatch 有个正数的计数器,countDown(); 对计数器做减法操作,await(); 等待计数器 = 0。所有await的线程都会阻塞,直到计数器为0或者等待线程中断或者超时。
1 public static void main(String[] args) throwsInterruptedException {2 //申明,等待事件数量 5次
3 CountDownLatch await = new CountDownLatch(5);4
5 //依次创建并启动处于等待状态的5个MyRunnable线程
6 for (int i = 1; i < 6; ++i) {7 new Thread(newMyRunnable(await, i)).start();8 }9
10 System.out.println("等待线程开始工作......");11 await.await();12 System.out.println("结束!");13 }
1 public static class MyRunnable implementsRunnable {2
3 private finalCountDownLatch await;4 private final intnum;5
6 public MyRunnable(CountDownLatch await, intnum) {7 this.await =await;8 this.num =num;9 }10
11 public voidrun() {12 try{13 System.out.println("线程"+num+"执行完毕。");14 await.countDown(); //当前事件执行完毕,计数 -1
15 } catch(InterruptedException e) {16 e.printStackTrace();17 }18 }19 }
运行结果:
等待线程开始工作......
线程1执行完毕。
线程2执行完毕。
线程3执行完毕。
线程4执行完毕。
线程5执行完毕。
结束!
流程如图所示:
图1 - CountDownLatch 处理流程
2. 栅栏(CyclicBarrier)
栅栏类似于闭锁,它能阻塞一组线程直到某个事件发生。 栅栏与闭锁的关键区别在于,所有的线程必须同时到达栅栏位置,才能继续执行。闭锁用于等待事件,而栅栏用于等待其他线程。
场景: 比如甲乙丙三人一把椅子,甲做椅子腿,乙做椅子面,丙做椅子靠背。等3人都做成后,就可以组装成椅子了。这是一种并行迭代,将一个问题分成很多子问题,当一系列的子问题都解决之后(所有子问题线程都已经await(); ),此时将栅栏打开,所有子问题线程被释放,而栅栏位置可以留着下次使用。
示例如下:
1 public static void main(String[] args) throwsInterruptedException {2 //申明,等待线程数量 3次
3 CyclicBarrier cyclicBarrier = new CyclicBarrier(3);4
5 //依次创建并启动处于等待状态的3个MyRunnable2线程
6 new Thread(new ChairRunnable(cyclicBarrier, "椅子腿")).start();7 new Thread(new ChairRunnable(cyclicBarrier, "椅子面")).start();8 new Thread(new ChairRunnable(cyclicBarrier, "椅子背")).start();9 }
1 public static class ChairRunnable implementsRunnable {2 private finalCyclicBarrier cyclicBarrier;3 private finalString event;4
5 publicChairRunnable(CyclicBarrier cyclicBarrier, String event) {6 this.cyclicBarrier =cyclicBarrier;7 this.event =event;8 }9
10 public voidrun() {11 try{12 System.out.println("开始做【" + event + "】。");13 Thread.sleep(new Random().nextInt(10000));14 cyclicBarrier.await(); //等待其他线程完成
15 } catch(InterruptedException e) {16 e.printStackTrace();17 } catch(BrokenBarrierException e) {18 e.printStackTrace();19 }20 System.out.println("【" + event + "】做好了, 我们来一起组装吧!");21 }22 }
运行结果:
开始做【椅子腿】。
开始做【椅子背】。
开始做【椅子面】。
【椅子面】做好了, 我们来一起组装吧!
【椅子腿】做好了, 我们来一起组装吧!
【椅子背】做好了, 我们来一起组装吧!
流程如下图所示:
图2 - CyclicBarrier 处理流程
-
多线程设计模式:Latch(门阀)设计模式
2021-04-10 18:50:231什么是Latch 若干线程并发执行某个特定的任务,然后等到所有的子任务都执行结束之后再统一汇总,比如用户想要查询自己三年以来银行账号的流水,为了保证运行数据库的数据量在一个恒定的范围之内,通常数据只会保存...1什么是Latch
若干线程并发执行某个特定的任务,然后等到所有的子任务都执行结束之后再统一汇总,比如用户想要查询自己三年以来银行账号的流水,为了保证运行数据库的数据量在一个恒定的范围之内,通常数据只会保存一年的记录,其他的历史记录或被备份到磁盘,或者被存储于hive数据仓库,或者被转存至备份数据库之中,总之想要三年的流水记录,需要若干个渠道的查询才可以汇齐。如果一个线程负责执行这样的任务,则需要经历若干次的查询最后汇总返回给用户,很明显这样的操作性能低下,用户体验差,如果我们将每一个渠道的查询交给一个线程或者若干个线程去查询,然后统一汇总,那么性能会提高很多,响应时间也会缩短不少。
Latch(门阀)设计模式,该模式指定了一个屏障,只有所有的条件都达到满足的时候,门阀才能打开。
2 CountDownLatch实现
2.1 无限等待的Latch
- 首先定义了一个无限等待的抽象类Latch,在Latch抽象类中定义了await方法、countDown方法以及getUnarrived方法
public abstract class Latch { /** * 用于控制多少个线程完成任务时,才能打开阀门 */ protected int limit; public Latch(int limit) { this.limit = limit; } /** * 抽象方法,该方法会使当前线程一直等待,直到所有 * 线程都完成工作,被阻塞的线程的是允许被中断的 */ public abstract void await() throws InterruptedException; /** * 当任务线程完成之后调用该方法使计数器减一 */ public abstract void countDown(); /** * 获取当前还有多少个线程没有完成任务 * @return */ public abstract int getUnArrived(); }
实现这些抽象方法
public class CountDownLatch extends Latch { public CountDownLatch(int limit) { super(limit); } @Override public void await() throws InterruptedException { synchronized (this) { // 当 limit > 0的时候,当前线程进入阻塞状态 while (this.limit > 0) { this.wait(); } } } @Override public void countDown() { synchronized (this) { if (limit <= 0) { throw new IllegalArgumentException("all of task already arrived"); } // limit -1, 并通知唤醒阻塞线程 this.limit--; this.notifyAll(); } } @Override public int getUnArrived() { // 返回当前还有多少个线程没有完成任务 return this.limit; } }
测试
public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(3); // 定义3个线程去,只有当三个线程都执行完了,主线程才会继续 Thread thread1 = new Thread("线程1") { @Override public void run() { System.out.println(Thread.currentThread().getName() + " start"); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " end"); countDownLatch.countDown(); } }; Thread thread2 = new Thread("线程2") { @Override public void run() { System.out.println(Thread.currentThread().getName() + " start"); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " end"); countDownLatch.countDown(); } }; Thread thread3 = new Thread("线程3") { @Override public void run() { System.out.println(Thread.currentThread().getName() + " start"); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " end"); countDownLatch.countDown(); } }; thread1.start(); thread2.start(); thread3.start(); // 等待三个线程执行结束 countDownLatch.await(); System.out.println("三个线程已经全部执行完毕"); }
线程2 start 线程1 start 线程3 start 线程1 end 线程2 end 线程3 end 三个线程已经全部执行完毕
2.2 增加超时设置
可以设置超时时间,最多等待多长时间,就不等了。
在抽象类中增加如下方法:
/** * 支持超时 */ public abstract void await(TimeUnit timeUnit,long time) throws InterruptedException, TimeoutException;
实现:
@Override public void await(TimeUnit timeUnit, long time) throws InterruptedException, TimeoutException { if (time <= 0) { throw new IllegalArgumentException("The time is invalid."); } // 剩余等待时间:将时间统一转化为纳秒 long remainingNanos = timeUnit.toNanos(time); // 计算超时结束时间 long endNanos = System.nanoTime() + remainingNanos; synchronized (this) { while (limit > 0) { // 如果超时了(剩余等待时间小于0),就抛出超时异常 if (TimeUnit.NANOSECONDS.toMillis(remainingNanos) <= 0) { throw new TimeoutException("等待超时"); } // 如果没有超时,那么就等待remainingNanos this.wait(TimeUnit.NANOSECONDS.toMillis(remainingNanos)); // 在等待的过程中有可能会被中断,需要重新计算remainingNanos: 超时结束时间 - 减去当前时间 remainingNanos = endNanos - System.nanoTime(); } } }
测试:将之前测试换成超时等待的方法
// 等待三个线程执行结束 try { countDownLatch.await(TimeUnit.SECONDS,2); } catch (TimeoutException e) { System.out.println("超时了,不在等待了,主线程继续执行"); }
线程2 start 线程3 start 线程1 start 线程1 end 线程2 end 超时了,不在等待了,主线程继续执行 三个线程已经全部执行完毕 线程3 end
3 CountDownLatch完整代码
public class CountDownLatch extends Latch { public CountDownLatch(int limit) { super(limit); } @Override public void await() throws InterruptedException { synchronized (this) { // 当 limit > 0的时候,当前线程进入阻塞状态 while (this.limit > 0) { this.wait(); } } } @Override public void await(TimeUnit timeUnit, long time) throws InterruptedException, TimeoutException { if (time <= 0) { throw new IllegalArgumentException("The time is invalid."); } // 剩余等待时间:将时间统一转化为纳秒 long remainingNanos = timeUnit.toNanos(time); // 计算超时结束时间 long endNanos = System.nanoTime() + remainingNanos; synchronized (this) { while (limit > 0) { // 如果超时了(剩余等待时间小于0),就抛出超时异常 if (TimeUnit.NANOSECONDS.toMillis(remainingNanos) <= 0) { throw new TimeoutException("等待超时"); } // 如果没有超时,那么就等待remainingNanos this.wait(TimeUnit.NANOSECONDS.toMillis(remainingNanos)); // 在等待的过程中有可能会被中断,需要重新计算remainingNanos: 超时结束时间 - 减去当前时间 remainingNanos = endNanos - System.nanoTime(); } } } @Override public void countDown() { synchronized (this) { if (limit <= 0) { throw new IllegalArgumentException("all of task already arrived"); } // limit -1, 并通知唤醒阻塞线程 this.limit--; this.notifyAll(); } } @Override public int getUnArrived() { // 返回当前还有多少个线程没有完成任务 return this.limit; } }
-
java多线程学习-java.util.concurrent详解(一) Latch/Barrier
2019-07-27 05:06:13NULL 博文链接:https://janeky.iteye.com/blog/769965 -
Java多线程-CountDownLatch
2022-02-16 14:39:06介绍 CountDownLatch是一个同步辅助类,它允许一个或多个线程一直等待直到...2:多线程读取Excel多个sheet,读取完成之后获取汇总获取的结果 3:多个人一起一起来吃饭,主人等待客人到来,客人一个个从不同地方来到饭店,主介绍
CountDownLatch是一个同步辅助类,它允许一个或多个线程一直等待直到其他线程执行完毕才开始执行。
用给定的计数初始化CountDownLatch,其含义是要被等待执行完的线程个数。
每次调用CountDown(),计数减1
主程序执行到await()函数会阻塞等待线程的执行,直到计数为0
场景
1:多线程读取批量文件, 并且读取完成之后汇总处理
2:多线程读取Excel多个sheet,读取完成之后获取汇总获取的结果
3:多个人一起一起来吃饭,主人等待客人到来,客人一个个从不同地方来到饭店,主人需要等到所有人都到来之后,才能开饭
4:汽车站,所有乘客都从不同的地方赶到汽车站,必须等到所有乘客都到了,汽车才会出发,(如果设置了超时等待,那么当某个时间点到了,汽车也出发)
5: 百米赛跑,4名运动员选手到达场地等待裁判口令,裁判一声口令,选手听到后同时起跑,当所有选手到达终点,裁判进行汇总排名
6: 4名选手进行大众投票,投票现场有500个票, 投票时间是30分钟,500个票投完结束投票,或者投票时间到了也结束投票
作用:可以用来确保某些活动直到其他活动都完成后才继续执行。
CountDownLatch非常适合于对任务进行拆分,使其并行执行,比如某个任务执行2s,其对数据的请求可以分为五个部分,那么就可以将这个任务拆分为5个子任务,分别交由五个线程执行,执行完成之后再由主线程进行汇总,此时,总的执行时间将决定于执行最慢的任务,平均来看,还是大大减少了总的执行时间。
注意事项:
-
使用CountDownLatch必须确保计数器数量与子线程数量一致,且countDown必须要执行,否则出现计数器不为0,导致主线程一致等待的情况
-
在执行任务的线程中,使用了
try...finally
结构,该结构可以保证创建的线程发生异常时CountDownLatch.countDown()方法也会执行,也就保证了主线程不会一直处于等待状态。
案例(模拟乘客登机的场景)
public static void main(String[] args) { CountDownLatchUtils.initialize("da1", 5); List<String> list=new CopyOnWriteArrayList<>(); ExecutorUtils.create(()->{ System.out.println("张三正在马鞍山,准备赶到南京坐飞机,需要1小时的车程到机场"); SleepTools.second(4); list.add("张三"); CountDownLatchUtils.countDown("da1"); }); ExecutorUtils.create(()->{ System.out.println("李四正在徐州,准备赶到南京坐飞机,需要5小时的车程到机场"); SleepTools.second(15); list.add("李四"); CountDownLatchUtils.countDown("da1"); }); ExecutorUtils.create(()->{ System.out.println("王五正在芜湖,准备赶到南京坐飞机,需要2小时的车程到机场"); SleepTools.second(9); list.add("王五"); CountDownLatchUtils.countDown("da1"); }); ExecutorUtils.create(()->{ //飞机起飞 CountDownLatchUtils.await("da1",10); //这里先模拟10秒 360秒=1小时 System.out.println("南京禄口机场_机长启动飞机起飞"); //当前航班已到乘客 System.out.println("当前航班已到乘客"+list); }); }
以上代码都是我封装后的,主要是看逻辑就行了
张三正在马鞍山,准备赶到南京坐飞机,需要1小时的车程到机场
李四正在徐州,准备赶到南京坐飞机,需要5小时的车程到机场
王五正在芜湖,准备赶到南京坐飞机,需要2小时的车程到机场
南京禄口机场_机长启动飞机起飞
当前航班已到乘客[张三, 王五]点赞 -收藏-关注-便于以后复习和收到最新内容 有其他问题在评论区讨论-或者私信我-收到会在第一时间回复 如有侵权,请私信联系我 感谢,配合,希望我的努力对你有帮助^_^ -
-
JAVA多线程-CountDownLatch计数器
2021-03-13 19:05:34一、概述CountDownLatch是一个同步工具类,它允许一个或多个线程等待其他线程执行完操作之后再继续执行。通常用于控制多个线程的执行顺序。二、基本原理我们可以把CountDownLatch看成是一个计数器,其内部维护着一个... -
多线程面试题——交替输出问题(Java)
2021-12-30 19:58:26有人可能会想到,用睡眠时间差来实现,但是只要是多线程里面,线程同步玩sleep()函数的,99.99%都是错的。 这道题其实有100多种解法。 最简单的解法,是这个问题的最优解,但其实不是面试官想听到的答案 关键函数 ... -
使用CountDownLatch实现多线程
2022-03-08 14:59:391、使用该方式是可以实现等待所有的线程执行完之后,在执行某些代码逻辑 2、使用CountDownLatch实现线程计数器-1,直到为0,await会被唤醒,再执行await之后的代码 -
多线程设计模式——二十二、Latch设计模式
2021-02-26 14:53:55Latch(阀门)设计模式也叫做 Count Down 设计模式。当若干个线程并发执行完某个特 定的任务,然后等到所有的子任务都执行结束之后再统一汇总。 CountDownLatch 能够使一个线程在等待另外一些线程完成各自工作之后,再... -
java多线程并发系列之闭锁(Latch)和栅栏(CyclicBarrier)原理分析
2019-07-10 11:46:58-闭锁(Latch) 闭锁(Latch):一种同步方法,可以延迟线程的进度直到线程到达某个终点状态。通俗的讲就是,一个闭锁相当于一扇大门,在大门打开之前所有线程都被阻断,一旦大门... -
spring多线程事务控制
2021-12-03 15:40:19话不多说直接上代码 ```/** * 将一组数据平均分成n组 * * @param source 要分组的数据源 * @param n 平均分成n组 * @param <T> * @return */ public static <T> List<List<T>> ... -
java redis 实现多线程资源复用
2022-01-17 16:14:085从队列获取资源 线程:thread-6从队列获取资源 线程:thread-7从队列获取资源 线程:thread-8从队列获取资源 线程:thread-9从队列获取资源 线程:thread-4获取到资源:A2 线程:thread-7获取到资源:A1 线程:... -
多线程往数据库添加数据
2022-01-08 11:54:10一、多线程写法: /** * @author liangyongpeng * @create 2022/1/7 9:44 */ @Slf4j public class RunnableImpCrmOutsideUtil implements Runnable { private final CrmCustOutsideMapper outsideMapper; ... -
c++多线程设计模式之一(Latch门阀模式)
2019-07-06 23:49:27使用场景: 多个任务同时完成,才能进入下一步时使用; #include <iostream> #include <thread> #include <mutex> #include <condition_variable> #include <random> #include &... -
多线程编程之 CountDownLatch
2021-06-22 15:20:47CountDownLatch 一般称为闭锁、计数器,是一种多线程同步工具,属于 AQS 体系的一员。 常用于让协调线程等待一组工作线程全部“完成工作“或“满足特定条件"后继续进行下去。 但其实也可以和 CyclicBarrier让一组... -
JAVA 实现多线程下载大文件
2021-12-28 15:22:09JAVA 实现多线程下载大文件 开发中遇到一个问题,下载大文件到本地,导致等待时间过长,然后就寻找一个可以多线程下载的办法,受下载软件启发,想到多线程下载, 原理,首先查到这个文件的大小,然后根据线程数量... -
多线程和HTTP异步
2021-05-30 18:09:21多线程和HTTP异步 场景 基于一个jvm下的批量执行业务。为了提高用户体验度。再多服务器多应用的情景下,使用多线程和HTTP异步。 注重点 ①数据重复消费 ②数据一致性 ③HTTP数据交互 业务实例 一、线程池配置 ... -
多线程的闭锁和栅栏
2021-08-01 13:36:52多线程的闭锁和栅栏 JAVA并发包中有三个类用于同步一批线程的行为,分别是闭锁(Latch),信号灯(Semaphore)和栅栏(CyclicBarrier)。这里我们主要来介绍一下: 闭锁(Latch) 闭锁即是一种同步方法,可以延迟... -
多线程并行处理数据
2020-09-01 17:08:08多线程并行处理数据 在工作中很多时候会因为各种原因选择使用多线程并行去处理我们要处理的数据,前段时间工作中就遇到了需要多线程去处理的业务逻辑情况,记录一下。 业务场景 在后台系统代码中,首先会拿到一些... -
Java 多线程Latch模式-对比IOS 的线程依赖
2020-04-29 12:19:52Latch 模式背景释义: 有A、B、C、D若干个并行任务,现在F任务需要等ABCD全部完成之后再进行,只要其中任一一个并发任务未执行完F任务就阻塞或者抛出超时异常、取消任务 代码翻译: 抽象任务接口约束类 ... -
多线程应用多接口合并执行
2020-11-04 19:35:30多线程:多个线程并行执行任务 最大优点:最大限度的利用CPU的空闲时间来处理其他任务,提高效率 多线程应用场景一: 一接口内部同时调用3个甚至更多的接口方法,正常情况下一个方法调用这些接口是同步执行的,... -
java多线程同步器
2021-03-14 21:52:44Java中多线程开发时,离不开线程的分工协作,常用的多线程的同步器有如下几种:1、CountDownLatch应用场景:等待一组线程任务完成后在继续执行当前线程。用法:定义一个CountDownLatch变量latch,在当前线程中调用... -
Java多线程下统计多个线程的运行时间
2021-03-10 03:11:29今天复习了一下java中Synchronized等关于多线程的问题。Synchronized是Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。Java的每个对象都有一个内部... -
多线程工作之Countdown latch样例
2020-04-29 17:34:48this.latch = latch; } @lombok.SneakyThrows @Override public void run() { int randomNum = ThreadLocalRandom.current().nextInt(1, 4); Thread.sleep(randomNum * 1000); log.info("HELLO WORLD: " + number);... -
JDBC多线程查询结果汇总
2021-02-26 19:53:18假设单线程查询SQL耗时1S,那么开启两个线程查询SQL理想情况下也是1S多点才对,机器是4核,但是目前结果近乎2倍显然有异;暂且不考虑从线程池获取连接,任务线程核心代码如下:@Overridepublic void run() {long s =... -
jdbc批处理+手动事务+多线程实现81秒插入千万数据(多线程版)
2021-02-01 21:35:43现在来试试多线程能够多少秒钟插入千万数据/*** @Author: guandezhi* @Date: 2019/4/13 15:35*/public class JdbcUtils {private static String url = "jdbc:mysql://localhost:3306/user?useSSL=false&... -
利用多线程对数组进行归并排序
2021-03-01 06:22:00多线程处理归并排序的方法一般为:假设有n个线程同步处理,就将数组等分成n份,每个线程处理一份,再对最后n个有序数组进行归并。为了使对整个算法具有可扩展性,即线程数n可以自定义,笔者将线程类、处理数组类等... -
Android多线程-并发实例记录
2021-05-26 19:31:06多线程基本概念java多线程状态图.jpgJava线程五种基本状态:1)新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();2)就绪状态(Runnable):当调用线程对象的start()方法(t.start...