一:多线程的2种实现方式
1: 继承Thread类
class MyThread1 extends Thread {
public void run() {
System.out.println("我是多綫程1");
}
}
public class Test1 {
public static void main(String[] args) throws InterruptedException {
MyThread1 thread1=new MyThread1();
thread1.start();
}
}
2:实现Runnable接口
class MyThread2 implements Runnable {
@Override
public void run() {
System.out.println("我是多线程2");
}
}
public class Test1 {
public static void main(String[] args) throws Exception {
MyThread2 mt = new MyThread2();
Thread t1 = new Thread(mt);
t1.start();
}
}
3:Join方法的使用
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.print(Thread.currentThread().getName() + " ");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.print(Thread.currentThread().getName() + " ");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t1.start();
t1.join();
t2.start();
二:ThreadGroup
class MyThread extends Thread
{
public MyThread(ThreadGroup tg, String name) {
super(tg, name);
}
public void run() {
System.out.println("ThreadName = " + Thread.currentThread().getName() + "准备开始死循环了");
while (!this.isInterrupted()) {
}
System.out.println("ThreadName = " + Thread.currentThread().getName() + "结束了");
}
}
public class Test1 {
public static void main(String[] args) throws InterruptedException {
ThreadGroup tg = new ThreadGroup("我的线程组");//创建一个线程组 ThreadGroup(ThreadGroup parent, String name)
MyThread mt = null;
for (int i = 0; i < 3; i++) {
mt = new MyThread(tg, "线程" + i);//将线程加入到线程组去
mt.start();
}
Thread.sleep(2000);
System.out.println("线程组活跃数:"+tg.activeCount());//返回线程组的活跃线程数
tg.interrupt();//中断线程组
System.out.println("调用了interrupt()方法");
}
三:ThreadPoolExecutor
//ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,TimeUnit,workQueue,RejectedExecutionHandler);
ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 30, 30, TimeUnit.MINUTES,
new ArrayBlockingQueue<Runnable>(10), new AbortPolicy());
for (int i = 1; i < 100; i++) {
System.out.println("提交第" + i + "个任务");
pool.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(">>>task is running========");
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
pool .shutdown();
if(!pool .awaitTermination(10, TimeUnit.SECONDS)) {
List<Runnable> runnables=pool .shutdownNow();
}
参数名 | 作用 |
corePoolSize | 核心线程池大小 |
maximumPoolSize | 最大线程池大小 |
keepAliveTime | 线程池中超过corePoolSize数目的空闲线程最大存活时间;可以allowCoreThreadTimeOut(true)使得核心线程有效时间 |
TimeUnit | keepAliveTime时间单位 |
workQueue | 阻塞任务队列 |
threadFactory | 新建线程工厂 |
RejectedExecutionHandler | 当提交任务数超过maxmumPoolSize+workQueue之和时,任务会交给RejectedExecutionHandler来处理 |
1:当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。
2:当线程池达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行。
3:当workQueue已满,且maximumPoolSize>corePoolSize时,新提交任务会创建新线程执行任务。
4:当提交任务数超过maximumPoolSize时,新提交任务由RejectedExecutionHandler处理。
5:当线程池中超过corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程。
6:当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭。
(1)workQueue
//LinkedBlockingQueue,ArrayBlockingQueue 的区别
阻塞队列LinkedBlockingQueue和ArrayBlockingQueue的区别 - 简书
SynchronousQueue:
这个队列接收到任务的时候,会直接提交给线程处理,而不保留它,如果所有线程都在工作,那就新建一个线程来处理这个任务.使用这个类型队列的时候,maximumPoolSize一般指定成Integer.MAX_VALUE。
LinkedBlockingQueue:
这个队列接收到任务的时候,如果当前线程数小于核心线程数,则新建线程(核心线程)处理任务;如果当前线程数等于核心线程数,则进入队列等待。由于这个队列没有最大值限制(新版本可以指定容量,如果不指定容量,默认是Integer.MAX_VALUE),即所有超过核心线程数的任务都将被添加到队列中,这也就导致了maximumPoolSize的设定失效,因为总线程数永远不会超过corePoolSize。
ArrayBlockingQueue:
可以限定队列的长度,接收到任务的时候,如果没有达到corePoolSize的值,则新建线程(核心线程)执行任务,如果达到了,则入队等候,如果队列已满,则新建线程(非核心线程)执行任务,又如果总线程数到了maximumPoolSize,并且队列也满了,则发生错误。
(2)RejectedExecutionHandler
AbortPolicy :
默认。直接抛异常。
CallerRunsPolicy :
只用调用者所在的线程执行任务,重试添加当前的任务,它会自动重复调用execute()方法,调用者线程性能可能急剧下降。
DiscardOldestPolicy :
丢弃任务队列中最久的任务。
DiscardPolicy :
丢弃当前任务。
自定义方式
class CustomRejectedExecutionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
//改成put阻塞方法
try {
executor.getQueue().put(r);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
四:java自带的几种线程池
1:newCachedThreadPool
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();//coreSize:0; 默认最大size是Integer.MAX_VALUE
for (int i = 0; i < 10; i++) {
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println("run");
}
});
}
2:newFixedThreadPool
ExecutorService fixthreadPool = Executors.newFixedThreadPool(2);
for (int i = 0; i < 10; i++) {
fixthreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println("run");
}
});
}
3:newScheduledThreadPool
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
//延时执行任务
scheduledThreadPool.schedule(new Runnable() {
@Override
public void run() {
System.out.println("delay 2 seconds");
}
}, 2, TimeUnit.SECONDS);
//延时周期性执行任务
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("delay 1 seconds, and excute every 3 seconds");
}
}, 1, 3, TimeUnit.SECONDS);
4:newSingleThreadExecutor
ExecutorService fixthreadPool = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
fixthreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println("run");
}
});
}
五:Future
//实现Callable接口
class MyThread2 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
return 1;
}
}
public class Test1 {
public static void main(String[] args) throws Exception {
// 创建一个固定线程数的线程池
ExecutorService executorService = Executors.newFixedThreadPool(1);
// 自定义内部类实现Callable 执行实际运行内容
MyThread2 oneThread = new MyThread2();
// 开启线程
Future<Integer> future1 = executorService.submit(oneThread);
// 开启线程
int num = 0;
try {
num = future1.get();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(num);
}
六:CompletionService
class Task implements Callable<Integer> {
Integer i;
public Task(Integer i) {
super();
this.i = i;
}
@Override
public Integer call() throws Exception {
System.out.println("线程:" + Thread.currentThread().getName() + "任务i=" + i + ",执行完成!");
return i;
}
}
public class Test1 {
public static void main(String[] args) throws Exception {
// 开启5个线程
ExecutorService exs = Executors.newFixedThreadPool(5);
try {
int taskCount = 10;
// 结果集
List<Integer> list = new ArrayList<Integer>();
// 1.定义CompletionService
CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(exs);
// 2.添加任务
for (int i = 0; i < taskCount; i++) {
Future<Integer> future = completionService.submit(new Task(i + 1));
}
// 3.获取结果
for (int i = 0; i < taskCount; i++) {
Integer result = completionService.take().get();
System.out.println("任务i==" + result + "完成!" + new Date());
list.add(result);
}
System.out.println("list=" + list);
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭线程池
exs.shutdown();
}
}