图文详解Java线程和线程池
什么是线程
线程是操作系统能够进行运算调度的最小单位。一个进程可以包含多个线程,线程共享进程资源,但是是CPU分配资源的独立单位。
Java中的线程
Java中的线程是使用Thread类对象来创建。Java中的线程有以下几种状态:新建状态、可运行状态、阻塞状态和死亡状态。在Java中,实现多线程有两种方式,一是继承Thread类,二是实现Runnable接口。
继承Thread类
继承Thread类可以通过重写run()方法来实现多线程。
public class MyThread extends Thread {
public void run(){
System.out.println("MyThread running");
}
}
MyThread thread = new MyThread();
thread.start();
实现Runnable接口
实现Runnable接口可以通过重写run()方法来实现多线程。与继承Thread类相比,实现Runnable接口可以更好的利用类的继承树,可以多个线程共享一个Runnable对象。
public class MyRunnable implements Runnable {
@Override
public void run(){
System.out.println("MyRunnable running");
}
}
MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start();
线程池
线程池是用来保存一定数量的线程,随时用于处理任务。线程池中线程的数量是可以动态调整的,这样可以避免为每一个任务都创建线程导致的资源浪费和过度使用系统资源的问题。Java中的线程池是通过ThreadPoolExecutor实现的。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
参数说明
参数 | 说明 |
---|---|
corePoolSize | 线程池维护的最少线程数量。 |
maximumPoolSize | 线程池维护的最大线程数量。 |
keepAliveTime | 线程池维护的线程的空闲时间。规定时间后,线程没有任务会被销毁。 |
workQueue | 用于保存任务的阻塞队列。 |
threadFactory | 线程工厂,用于创建线程。 |
handler | 在任务被拒绝添加时,用于处理rejectedExecution。 |
示例1
public class ThreadPoolDemo {
static class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " is running");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
for (int i = 0; i < 5; i++) {
executorService.execute(new MyRunnable());
}
executorService.shutdown();
}
}
以上代码创建了一个固定大小为2的线程池,总共有5个任务需要执行,结果会将任务平均分配到两个线程中运行。通过调整corePoolSize和maximumPoolSize,我们可以改变线程池的大小。
示例2
public class ThreadPoolDemo {
static class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " is running");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService executorService = new ThreadPoolExecutor(2, 4,
5,TimeUnit.SECONDS,new LinkedBlockingDeque<>(5));
for (int i = 0; i < 10; i++) {
executorService.execute(new MyRunnable());
}
executorService.shutdown();
}
}
以上代码创建了一个核心池大小为2,最大池大小为4的线程池,线程池使用LinkedBlockingDeque存储任务。当线程池中没有空闲线程时,新任务会被加入到LinkedBlockingDeque中。有界队列可以有效防止资源耗尽的情况。
通过以上两个示例我们可以了解Java线程和线程池相关的知识,学习和运用这些知识可以有效提高Java程序的性能和资源利用率。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:图文详解Java线程和线程池 - Python技术站