一、实现Java多线程的方法
1、继承Thread类创建多线程
Thread类本质实现了Runnable接口。启动线程为start0()方法。是个native方法。
1 public class ThreadProcess extendsThread {2
3 @Override4 public voidrun(){5 long lastTime =System.currentTimeMillis();6 for(int i = 0; i < 1; i++){7 int ele =Integer.MAX_VALUE;8 while (ele >= 0){9 int ele2 = ele - Integer.MAX_VALUE + 65535 - 37666 + 44443;10 int temp =Math.max(ele2, ele);11 if(temp !=ele){12 temp =ele;13 }14 ele = temp-1;15 }16 }17 System.out.println("Time cost from thread " + (System.currentTimeMillis() -lastTime));18 }19 }
2、实现Runnable。一个类已经继承了Thread类就无法继承其它类。
1 class AccountOperator implementsRunnable {2 private intcount;3 private final byte[] lock = new byte[0];4
5 publicAccountOperator() {6 this.count = 0;7 }8
9 public voidrun() {10 synchronized(lock) {11 count++;12 System.out.println(Thread.currentThread().getName() + ":" +count);13 }14 }15 }
3、实现Callable
如果运行完线程并且需要线程返回结果的时候,可以
1 importjava.util.concurrent.Callable;2
3 public class GetDataThread implements Callable{4 privateV v;5
6 publicGetDataThread(V v) {7 this.v =v;8 }9
10 @Override11 publicV call() {12 return this.v;13 }14 }
1 public classMain {2 public static void main(String[] args) throwsException{3 String data = "data";4 FutureTask ft = new FutureTask<>(new GetDataCal<>(data));5 Thread t = newThread(ft);6 t.start();7 String res =ft.get();8 System.out.println("Result: " +res);9 }10 }
二、Java线程池
线程的创建和销毁是需要时间的。记线程创建的时间为T1, 线程运行的时间为T2,线程销毁的时间为T3。如果T1 + T3 远远大于 T2,并且有很多这样的任务需要并行执行时,就可以使用线程池。
因为通过线程池,线程资源可以重复使用。
1、常见的线程池
newSingleThreadExecutor
newFixedThreadExecutor
newCachedThreadExecutor
newScheduleThreadExecutor
2、首先看下ThreadPoolExecutor方法。构造函数包含了几个重要参数,
1 public ThreadPoolExecutor(intcorePoolSize,2 intmaximumPoolSize,3 longkeepAliveTime,4 TimeUnit unit,5 BlockingQueueworkQueue6 RejectedExecutionHandler handler){}
corePoolSize, 线程池核心线程数量
maximumPoolSize,线程池最大线程数
keepAliveTime,当活跃线程数大于核心线程数时,空闲的多余线程最大存活时间
unit 存活时间的单位
workQueue 存放任务的队列
handler 超出线程范围和队列容量的任务的处理程序,也叫拒绝策略。
3、先看下线程池的实现原理
提交一个任务到线程池,线程池的处理流程如下
判断核心线程池是否都在执行任务,如果不是,则创建新的线程执行任务
若核心线程都在执行任务,判断工作队列满没满,如果没满,把任务提交给队列
若队列满了,判断线程池里的线程是否都处于工作状态。如果没有,则创建一个新的工作线程来执行任务,如果满了则交给拒绝策略处理