Java线程池应用

Posted 奔跑在梦想的道路上

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java线程池应用相关的知识,希望对你有一定的参考价值。

在Java中,多线程有着广泛运用。在实际应用中,好的软件设计不建议手动创建和销毁线程。线程的创建和销毁是非常耗 CPU 和内存资源的,因为这需要 JVM 和操作系统的参与。为此,我们在面临多线程问题时,通常会采用线程池。一般情况下,每个线程池会由这些模块组成:一个任务队列,一个工作线程的集合,一个线程工厂,管理线程状态的元数据。

线程池可以解决两个问题:一是由于减少了每个任务调用的开销,它们通常可以在执行大量异步任务时提供增强的性能,并且还可以提供绑定和管理资源(包括执行任务集时使用的线程)的方法;二是每个 ThreadPoolExecutor 还维护着一些基本的统计数据,如完成的任务数。 

线程池均位于 java.util.concurrent包中。

ThreadPoolExecutor类的继承关系为:

public class ThreadPoolExecutor extends AbstractExecutorService

其中,抽象类 AbstractExecutorService的继承关系为:

 public abstract class AbstractExecutorService extends Object implements ExecutorService

ExecutorService接口的继承关系为:

public interface ExecutorService extends Executor 

Executor是一个顶级接口。

在实际应用中,我们可以采用Executors的工厂方法Executors.newCachedThreadPool()(无界限程池,可以进行自动线程回收),Executors.newFixedThreadPool(int)(固定大小线程池),或Executors.newSingleThreadExecutor()(单个后台线程)来生成线程池,这些方法生成的线程池均为大多数使用场景预定义了设置。

Executors的的继承关系为:

public class Executors extends Object 

由于创建子线程可以有继承Thread类,实现Runnable接口,以及实现Callable接口三种方式,所以,我这里先通过这三种方式创建线程,然后再通过一个测试类通过线程池来运行。

MyThread.java中的代码如下:

public class MyThread extends Thread{
public MyThread(String name){
super(name);
}
int num=10;
@Override
public void run() {
while(num>=0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName()+"正在数:"+num);
num--;
}
}
}

MyRun.java中的代码如下:

public class MyRun implements Runnable {
public MyRun(String name){
Thread.currentThread().setName(name);
}
int num=10;
@Override
public void run() {
while(num>=0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在数:"+num);
num--;
}
}
}

MyCall.java中的代码如下:

public class MyCall implements Callable<String> {
int num=10;
@Override
public String call() throws Exception {
while(num>=0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在数:"+num);
num--;
}
return Thread.currentThread().getName()+"顺利执行";
}
}

测试文件Test.java中的代码如下:

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
public class Test {
//采用newFixedThreadPool()方法创建线程池,设置线程池中有2个线程
static ThreadPoolExecutor pool=(ThreadPoolExecutor) Executors.newFixedThreadPool(2);
//或者采用下述方式生成线程连接池
// static ExecutorService pool=Executors.newFixedThreadPool(2);
public static void main(String[] args) {
Future<String> s1 = pool.submit(new MyCall());
Future<String> s2 = pool.submit(new MyCall());
try {
System.out.println(s1.get());
System.out.println(s2.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//切记:线程池不是线程执行结束就终止,而是手动终止
pool.shutdown();
}
public static void main2(String[] args) {
pool.submit(new MyRun("张三"));
pool.submit(new MyRun("李四"));
pool.submit(new MyRun("王五"));
pool.submit(new MyRun("赵六"));
//切记:线程池不是线程执行结束就终止,而是手动终止
pool.shutdown();
}
public static void main1(String[] args) {
pool.submit(new MyThread("张三"));
pool.submit(new MyThread("李四"));
pool.submit(new MyThread("王五"));
pool.submit(new MyThread("赵六"));
//切记:线程池不是线程执行结束就终止,而是手动终止
pool.shutdown();
}
}

以上是关于Java线程池应用的主要内容,如果未能解决你的问题,请参考以下文章

Java线程池详解

Java 线程池详解

newCacheThreadPool()newFixedThreadPool()newScheduledThreadPool()newSingleThreadExecutor()自定义线程池(代码片段

Java线程池详解

IDEA对新建java线程池的建议

Java线程池创建方式和应用场景