java技术深入(一)

1、线程池好处

首先,由于涉及到与操作系统交互,线程创建是需要付出一定代价的,众多待命的空闲线程随时准备提供服务可以提高效率。如果需要大量的生命期很短的线程,就应该使用线程池。

其次,线城池可以减少并发线程的数量,大量创建线程会大大降低性能,甚至使虚拟机崩溃。如果有一个会创建大量线程的算法,就应该使用线程数固定的线程池以限制并发线程总数

2、线程池如何工作

线程池中可缓存大量随时准备运行的空闲线程。新建线程池对象之后,将Runnable对象交给线程池,就会由其中的一个线程调用run方法。当run方法退出时,线程不会死亡,而是被线程池回收,准备为下一个请求服务。

3、执行器(Executors类)

Executors类提供了许多静态方法来构建各种线程池:

a、newCacheThreadPool:构建一个线程池,线程数目不限。有任务到达时,如果有空闲线程就立即执行任务,没有的话就新建线程。执行任务之后的线程会保留60秒,如果在60秒之内没有接到新任务就销毁线程。

b、newFixedThreadPool:构造一个线程数量固定的线程池,如果提交的任务多于空闲线程数,那么新任务将放置到等待队列中。

c、newSingleThreadExecutor:线程数为1的线程池。

这三个创建线程池的方法均返回一个实现了ExecutorService接口的ThreadPoolExecutor类的对象。调用这个线程池对象的submit方法,传入Runnable对象或者Callable对象,线程池将会在方便的时候执行提交的任务。

当一个线程池不再需要的时候,调用其shutdown函数可以将其安全地关闭。shutdown函数被调用后,线程池对象将不再接受新的任务,等待所有已接受任务完成之后,线程池对象将被销毁。也可以调用shutdownNow方法,该方法意味着取消已接受但尚未执行的任务,尝试中断正在执行的任务,待所有线程关闭后销毁线程池。

4、实例

/ThreadPoolTest/src/IOnCallBack.java

public interface IOnCallBack{ public void onCallBack(char c);}

/ThreadPoolTest/src/MyRunnable.java

public class MyRunnable implements Runnable{ private String str; private int index; private IOnCallBack icall; public MyRunnable(String _str, int _index, IOnCallBack _icall) { str = _str; index = _index; this.icall = _icall; } @Override public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } icall.onCallBack(str.toCharArray()[index]); }}

/ThreadPoolTest/src/MyCallable.java文件:

import java.util.concurrent.Callable;//Callable类似于Runnable接口,实现Runnable、Callable接口的类都可被其他线程异步执行//Callable和Runnable的区别在于://1、Callable定义的方法是call,而Runnable定义的方法是run。//2、Callable的call方法可以有返回值,而Runnable的run方法不能有返回值。//3、Callable的call方法可抛出异常,而Runnable的run方法不能抛出异常。 public class MyCallable implements Callable{ private String str; private int index; public MyCallable(String _str, int _index) { str = _str; index = _index; } @Override public Object call() throws Exception { Thread.sleep(5000); return str.toCharArray()[index]; }}

/ThreadPoolTest/src/Test.java文件:

import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;public class Test{ /** * @param args */ public static void main(String[] args) { ExecutorService pool = Executors.newFixedThreadPool(10); MyRunnable run = new MyRunnable("yuyong", 2, new IOnCallBack() { @Override public void onCallBack(char c) { System.out.println(c + ":run"); } }); pool.submit(run); System.out.println("任务已提交:run"); // —————————————————————– ExecutorService pool_single = Executors.newSingleThreadExecutor(); MyCallable call = new MyCallable("yuyong", 2); // Future表示异步计算的结果,,它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。 // Future的cancel方法可以取消任务的执行。它有一布尔参数,参数为true 表示立即中断任务的执行,参数为 false // 表示允许正在运行的任务运行完成。 // Future的 get方法是一个同步方法,调用时会阻塞调用线程等待计算完成,获取计算结果。 Future f = pool_single.submit(call); System.out.println("任务已提交:call"); try { System.out.println(((char) f.get()) + ":call"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }}

结果如下:

如果前世五百次眸回,才换来今生的擦肩而过。

java技术深入(一)

相关文章:

你感兴趣的文章:

标签云: