Java 基础之线程池的必要性

在最近的几次面试中都被问到了线程的获取方式。我都是把基本的方法回答了一下。即实现Runnable接口或者继承Thread 这两种方法。而几次的回答面试官好像都不是太满意。今天特意梳理一下这个问题,JAVA线程的获取方式。JAVA 的线程获取方式主要有三种方式:

1.实现Runnable 接口

2.继承Thread 类

3.通过线程池来获取线程(四种线程池)

第一种和第二种方式都比较简单,这里主要来分析一线程池的必要性。

       理解线程池最主要的是要区分任务和线程这两个概念,线程是用来处理任务的。任务的创建是通过Runnable 接口来创建的,而线程则是通过实例化Thread 这个类的对象来创建的。我们是通过实现Runnable接口提交任务。看下面的例子:

import java.util.ArrayList;


  class ThreadTest {
	  
	public static void main(String []args){
		

     	Task task=new Task("TaskA");
		
		for(int i=0;i<5;i++){			

			Thread thread=new Thread(task);//创建一个线程
		     thread.start();//在线程thread里执行任务task
		    
		     
		}

	}	
}
class Task implements Runnable{
   
	String taskName;
	Task(String taskName){
		this.taskName=taskName;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		System.out.println("这是一个任务!"+this.taskName);
		
	}

}




 类Task 实现了Runnable接口并且实现里run()方法,run()方法里是任务执行的具体过程,在本例中任务是打印字符串“这是一个任务+任务的名字”。在ThreadTest中,首先实例化一个名为TaskA 的任务。之后通过五次循环来创建并启动五个线程,注意此处,虽然创建了5个线程,但是五个线程却执行同一个任务即TaskA,因此输出结果为: 

这是一个任务!TaskA
这是一个任务!TaskA
这是一个任务!TaskA
这是一个任务!TaskA
这是一个任务!TaskA

对上例的类ThreadTest进行改进如下:


class ThreadTest {
	public static void main(String []args){
		
	  
		
		for(int i=0;i<5;i++){			
	     	Task task=new Task("Task-->"+i);//创建一个任务
		Thread thread=new Thread(task);//创建一个线程
		thread.start();//在线程thread里执行任务task
		}

	}
	
	
}
 

 执行结果:

这是一个任务!Task0
这是一个任务!Task2
这是一个任务!Task3
这是一个任务!Task1
这是一个任务!Task4




这个例子的意思是:在for循环中,每创建一个任务即对应一个线程,然后用此线程执行该任务。通过执行结果可以看出五个线程执行了五个不同的任务,且这几个线程的执行顺序是不确定。现在问题来了,当任务非常多甚至达到成千上万的规模时,如果仍然采用这种方式,那么假如有一百万个任务,我就要创建对应的一百万个线程来执行这些任务。而每个线程的创建、销毁是非常耗费系统资源的,试想一下创建一百万个线程,系统肯定会内存溢出。那么现在该怎么处理这个事呢?对每个任务都创建一个对应的线程来执行它是不现实的。试想,可不可让一个线程去执行多个任务呢?这样的话,一个线程就对应多个任务。而我们所需要的创建的线程数就会成倍的下降。显然这是可以的,这就是线程池的概念。线程池的出发点便是为了节省系统资源,让一个线程再执行完一个任务后继续执行另一个任务。(注意,在Thread 类的实例被创建并通过start方法启动后便不可以再次被启动了,所以通过Thread 方式不能实现一个线程对应多个任务,只能通过线程池来实现)。








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值