多线程的使用
使用线程池ExecutorService
,exe.execute
来开始线程,thread,runabble,callabble
都可以,isTerminated
来判断线程池的线程是否都执行完毕
@Testpublic void testThread() throws InterruptedException {//创建线程池ExecutorService exe = Executors.newFixedThreadPool(50);for (int i = 1; i <= 1000; i++) {//执行线程exe.execute(new Runnable() {@Overridepublic void run() {System.out.println("1-->"+System.currentTimeMillis());}});//执行线程exe.execute(new Runnable() {@Overridepublic void run() {System.out.println("2-->"+System.currentTimeMillis());}});//执行线程exe.execute(new Runnable() {@Overridepublic void run() {System.out.println("3-->"+System.currentTimeMillis());}});//执行线程exe.execute(new Runnable() {@Overridepublic void run() {System.out.println("4-->"+System.currentTimeMillis());}});}while (true) {//判断线程是否都执行完毕if (exe.isTerminated()) {System.out.println("结束了!");break;}//睡眠一会再检查是否执行完毕Thread.sleep(200);}//关闭线程池exe.shutdown();}
使用场景:生成报告,要填充数据、表格、图表,生成时间太久,优化方案,数据、表格、图表的数据sql,然后判断线程都执行完毕后,再执行整合插入的方法,来缩短报告生成时间
ThreadLocal和InheritableThreadLocal
ThreadLocal
为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本,但是存在一个问题
,就是子线程获取该值的时候为Null
,可以用InheritableThreadLocal代替ThreadLocal
,依旧会为每个线程提供一个独立的副本,而不会共享
- ThreadLocal
@Testpublic void test2() throws InterruptedException {ThreadLocal num=new ThreadLocal();num.set(100);new Thread(()->{System.out.println(num.get());}).start();Thread.sleep(1000);System.out.println("完成");}
可以看到值为空
2. InheritableThreadLocal
@Testpublic void test2() throws InterruptedException {//ThreadLocal变量无法传到子线程中使用,InheritableThreadLocal就是为了解决这个问题InheritableThreadLocal num=new InheritableThreadLocal();num.set(100);new Thread(()->{System.out.println(num.get());}).start();Thread.sleep(1000);System.out.println("完成");}
正常取到值