我们大家都知道,在处理多线程服务并发时,由于创建线程需要占用很多的系统资源,所以为了避免这些不必要的损耗,通常我们采用线程池来解决这些问题。
线程池的基本原理是,首先创建并保持一定数量的线程,当需要使用线程时,我们从池中取得线程,再将需要运行的任务交给线程进行处理,当任务完成后再将其释放回池中
线程池:
先看一个例子
package thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestService {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ExecutorService es=Executors.newFixedThreadPool(2);
for(int i=0;i<100;i++){
Runnable r=new Runnable(){
public void run(){
long time=(long)(Math.random()*1000);
System.out.println("休眠"+time+"ms");
try{
Thread.sleep(time);
}catch(InterruptedException ee){
}
}
};
es.execute(r);
}
es.shutdown();
}
}
执行结果;
休眠861ms
休眠65ms
休眠356ms
休眠347ms
休眠556ms
休眠6ms
休眠565ms
休眠368ms
休眠842ms
休眠546ms
休眠178ms
休眠64ms
休眠479ms
休眠851ms
休眠153ms
休眠219ms
休眠820ms
休眠618ms
休眠558ms
休眠444ms
休眠447ms
休眠326ms
休眠124ms
休眠298ms
休眠886ms
休眠801ms
休眠657ms
以上是2个大小的线程池来处理100个线程。需要注意的是,线程池必须使用shutdown来显式关闭,否则会造成主线程无法退出。shutdown也不会阻塞主线程。
但是有一个问题:在for循环的过程中,会等待线程池有空闲的线程,所以主线程会阻塞,为了解决这个问题,一般启动一的线程来做for循环,就是避免由于线程池满会造成主线程阻塞,代码如下:
package thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestService extends Thread{
public void run(){
ExecutorService es=Executors.newFixedThreadPool(2);
for(int i=0;i<100;i++){
Runnable r=new Runnable(){
public void run(){
long time=(long)(Math.random()*1000);
System.out.println("休眠"+time+"ms");
try{
Thread.sleep(time);
}catch(InterruptedException ee){
}
}
};
es.execute(r);
}
es.shutdown();
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new TestService().start();
}
}
线程池的基本原理是,首先创建并保持一定数量的线程,当需要使用线程时,我们从池中取得线程,再将需要运行的任务交给线程进行处理,当任务完成后再将其释放回池中
线程池:
先看一个例子
package thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestService {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ExecutorService es=Executors.newFixedThreadPool(2);
for(int i=0;i<100;i++){
Runnable r=new Runnable(){
public void run(){
long time=(long)(Math.random()*1000);
System.out.println("休眠"+time+"ms");
try{
Thread.sleep(time);
}catch(InterruptedException ee){
}
}
};
es.execute(r);
}
es.shutdown();
}
}
执行结果;
休眠861ms
休眠65ms
休眠356ms
休眠347ms
休眠556ms
休眠6ms
休眠565ms
休眠368ms
休眠842ms
休眠546ms
休眠178ms
休眠64ms
休眠479ms
休眠851ms
休眠153ms
休眠219ms
休眠820ms
休眠618ms
休眠558ms
休眠444ms
休眠447ms
休眠326ms
休眠124ms
休眠298ms
休眠886ms
休眠801ms
休眠657ms
以上是2个大小的线程池来处理100个线程。需要注意的是,线程池必须使用shutdown来显式关闭,否则会造成主线程无法退出。shutdown也不会阻塞主线程。
但是有一个问题:在for循环的过程中,会等待线程池有空闲的线程,所以主线程会阻塞,为了解决这个问题,一般启动一的线程来做for循环,就是避免由于线程池满会造成主线程阻塞,代码如下:
package thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestService extends Thread{
public void run(){
ExecutorService es=Executors.newFixedThreadPool(2);
for(int i=0;i<100;i++){
Runnable r=new Runnable(){
public void run(){
long time=(long)(Math.random()*1000);
System.out.println("休眠"+time+"ms");
try{
Thread.sleep(time);
}catch(InterruptedException ee){
}
}
};
es.execute(r);
}
es.shutdown();
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new TestService().start();
}
}