`
廖世勇
  • 浏览: 91524 次
  • 性别: Icon_minigender_1
  • 来自: 湖南郴州
社区版块
存档分类
最新评论

JAVA多线程

 
阅读更多


ThreadPoolService(线程池服务类):这是线程池最核心的一个类。它在被创建了时候就创建了几个线程对象,但是这些线程并没有启动运行,但调用了start()方法启动线程池服务时,它们才真正运行。stop()方法可以停止线程池服务,同时停止池中所有线程的运行。而runTask(Tasktask)方法是将一个新的待执行任务交与线程池来运行。
ThreadPoolService类的定义如下:

Java代码

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. public class ThreadPoolService {
  4. // 线程数
  5. public static final int THREAD_COUNT = 5;
  6. // 线程池状态
  7. private Status status = Status.NEW;
  8. private TaskQueue queue = new TaskQueue();
  9. public enum Status {
  10. /* 新建 */NEW, /* 提供服务中 */RUNNING, /* 停止服务 */TERMINATED,
  11. }
  12. private List<Thread> threads = new ArrayList<Thread>();
  13. public ThreadPoolService() {
  14. for (int i = 0; i < THREAD_COUNT; i++) {
  15. Thread t = new TaskThread(this);
  16. threads.add(t);
  17. }
  18. }
  19. // 启动服务
  20. public void start() {


[/list]
完成了上面四个类,我们就实现了一个简单的线程池。现在我们就可以使用它了,下面的代码做了一个简单的示例:

Java代码

  1. public class SimpleTaskTest extends Task {
  2. @Override
  3. public void deal() {
  4. // do something
  5. }
  6. public static void main(String[] args) throws InterruptedException {
  7. ThreadPoolService service = new ThreadPoolService();
  8. service.start();
  9. // 执行十次任务
  10. for (int i = 0; i < 10; i++) {
  11. service.runTask(new SimpleTaskTest());
  12. }
  13. // 睡眠1秒钟,等待所有任务执行完毕
  14. Thread.sleep(1000);
  15. service.stop();
  16. }
  17. }

public class SimpleTaskTest extends Task {

@Override

public void deal() {

// do something

}

public static void main(String[] args) throws InterruptedException {

ThreadPoolService service = new ThreadPoolService();

service.start();

// 执行十次任务

for (int i = 0; i < 10; i++) {

service.runTask(new SimpleTaskTest());

}

// 睡眠1秒钟,等待所有任务执行完毕

Thread.sleep(1000);

service.stop();

}

}


当然,我们实现的是最简单的,这里只是为了演示线程池的实现原理。在实际应用中,根据情况的不同,可以做很多优化。比如:

  • 调整任务队列的规则,给任务设置优先级,级别高的任务优先执行。
  • 动态维护线程池,当待执行任务数量较多时,增加线程的数量,加快任务的执行速度;当任务较少时,回收一部分长期闲置的线程,减少对系统资源的消耗。


事实上Java5.0及以上版本已经为我们提供了线程池功能,无需再重新实现。这些类位于java.util.concurrent包中。

Executors类提供了一组创建线程池对象的方法,常用的有一下几个:

Java代码

  1. public static ExecutorService newCachedThreadPool() {
  2. // other code
  3. }
  4. public static ExecutorService newFixedThreadPool(int nThreads) {
  5. // other code
  6. }
  7. public static ExecutorService newSingleThreadExecutor() {
  8. // other code
  9. }

public static ExecutorService newCachedThreadPool() {

// other code

}

public static ExecutorService newFixedThreadPool(int nThreads) {

// other code

}

public static ExecutorService newSingleThreadExecutor() {

// other code

}


newCachedThreadPool()方法创建一个动态的线程池,其中线程的数量会根据实际需要来创建和回收,适合于执行大量短期任务的情况;newFixedThreadPool(int nThreads)方法创建一个包含固定数量线程对象的线程池,nThreads代表要创建的线程数,如果某个线程在运行的过程中因为异常而终止了,那么一个新的线程会被创建和启动来代替它;而newSingleThreadExecutor()方法则只在线程池中创建一个线程,来执行所有的任务。

这三个方法都返回了一个ExecutorService类型的对象。实际上,ExecutorService是一个接口,它的submit()方法负责接收任务并交与线程池中的线程去运行。submit()方法能够接受Callable和Runnable两种类型的对象。它们的用法和区别如下:

  1. Runnable接口:继承Runnable接口的类要实现它的run()方法,并将执行任务的代码放入其中,run()方法没有返回值。适合于只做某种操作,不关心运行结果的情况。
  2. Callable接口:继承Callable接口的类要实现它的call()方法,并将执行任务的代码放入其中,call()将任务的执行结果作为返回值。适合于执行某种操作后,需要知道执行结果的情况。


无论是接收Runnable型参数,还是接收Callable型参数的submit()方法,都会返回一个Future(也是一个接口)类型的对象。该对象中包含了任务的执行情况以及结果。调用Future的boolean isDone()方法可以获知任务是否执行完毕;调用Object get()方法可以获得任务执行后的返回结果,如果此时任务还没有执行完,get()方法会保持等待,直到相应的任务执行完毕后,才会将结果返回。

我们用下面的一个例子来演示Java5.0中线程池的使用:

Java代码

  1. import java.util.concurrent.*;
  2. public class ExecutorTest {
  3. public static void main(String[] args) throws InterruptedException,
  4. ExecutionException {
  5. ExecutorService es = Executors.newSingleThreadExecutor();
  6. Future fr = es.submit(new RunnableTest());// 提交任务
  7. Future fc = es.submit(new CallableTest());// 提交任务
  8. // 取得返回值并输出
  9. System.out.println((String) fc.get());
  10. // 检查任务是否执行完毕
  11. if (fr.isDone()) {
  12. System.out.println("执行完毕-RunnableTest.run()");
  13. } else {
  14. System.out.println("未执行完-RunnableTest.run()");
  15. }
  16. // 检查任务是否执行完毕
  17. if (fc.isDone()) {
  18. System.out.println("执行完毕-CallableTest.run()");
  19. } else {
  20. System.out.println("未执行完-CallableTest.run()");
  21. }
  22. // 停止线程池服务
  23. es.shutdown();
  24. }
  25. }
  26. class RunnableTest implements Runnable {
  27. public void run() {
  28. System.out.println("已经执行-RunnableTest.run()");
  29. }
  30. }
  31. class CallableTest implements Callable {
  32. public Object call() {
  33. System.out.println("已经执行-CallableTest.call()");
  34. return "返回值-CallableTest.call()";
  35. }
  36. }

import java.util.concurrent.*;

public class ExecutorTest {

public static void main(String[] args) throws InterruptedException,

ExecutionException {

ExecutorService es = Executors.newSingleThreadExecutor();

Future fr = es.submit(new RunnableTest());// 提交任务

Future fc = es.submit(new CallableTest());// 提交任务

// 取得返回值并输出

System.out.println((String) fc.get());

// 检查任务是否执行完毕

if (fr.isDone()) {

System.out.println("执行完毕-RunnableTest.run()");

} else {

System.out.println("未执行完-RunnableTest.run()");

}

// 检查任务是否执行完毕

if (fc.isDone()) {

System.out.println("执行完毕-CallableTest.run()");

} else {

System.out.println("未执行完-CallableTest.run()");

}

// 停止线程池服务

es.shutdown();

}

}

class RunnableTest implements Runnable {

public void run() {

System.out.println("已经执行-RunnableTest.run()");

}

}

class CallableTest implements Callable {

public Object call() {

System.out.println("已经执行-CallableTest.call()");

return "返回值-CallableTest.call()";

}

}


运行结果:

  1. 已经执行-RunnableTest.run()
  2. 已经执行-CallableTest.call()
  3. 返回值-CallableTest.call()
  4. 执行完毕-RunnableTest.run()
  5. 执行完毕-CallableTest.run()

使用完线程池之后,需要调用它的shutdown()方法停止服务,否则其中的所有线程都会保持运行,程序不会退出。

(转载http://zangweiren.javaeye.com

分享到:
评论

相关推荐

    Java多线程设计模式上传文件

    Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式...

    java多线程读取文件

    Java多线程读大文件 java多线程写文件:多线程往队列中写入数据

    java多线程ppt

    java多线程PPT 多线程基本概念 创建线程的方式 线程的挂起与唤醒 多线程问题

    java 多线程操作数据库

    一个java 多线程操作数据库应用程序!!!

    java多线程经典案例

    java多线程经典案例,线程同步、线程通信、线程阻塞等经典案例

    Java多线程编程实战指南(核心篇)

    Java多线程编程实战指南(核心篇) 高清pdf带目录 随着现代处理器的生产工艺从提升处理器主频频率转向多核化,即在一块芯片上集成多个处理器内核(Core),多核处理器(Multicore Processor)离我们越来越近了――如今...

    Java多线程知识点总结

    该文档总结了Java多线程相关的知识点,分享给大家,简单易懂!

    java多线程的讲解和实战

    详细的讲解了java多线程的原理,并配有代码进行实战,适合java初学者和想对多线程有进一步了解的人。

    java多线程通信图解

    一张图方便理解和掌握java 多线程之间通信的实质 java 多线程 其实就是每个线程都拥有自己的内存空间,多线程之间的通信,比例A线程修改了主内存(main方法的线程)变量,需要把A线程修改的结果同步到主线程中,...

    java多线程处理数据库数据

    java多线程处理数据库数据,使用并发包,无框架,可批量处数据库数据,进行增删改。。等等操作。

    java多线程,对多线程,线程池进行封装,方便使用

    java多线程,对多线程,线程池进行封装,方便使用

    Java多线程编程经验

    现在的操作系统是多任务操作系统。多线程是实现多任务的一种方式。 线程是指进程中的一个执行流程,一个进程中可以运行多个线程。...本文档提供Java多线程编程经验,方便广大Java爱好者研究学习Java多线程

    java多线程处理大数据

    java多线程处理大数据,可根据配置的线程数,任务去调度处理

    java多线程并发

    java多线程并发的在新窗口

    Java多线程机制(讲述java里面与多线程有关的函数)

    Java多线程机制 9.1 Java中的线程 9.2 Thread的子类创建线程 9.3 使用Runable接口 9.4 线程的常用方法 9.5 GUI线程 9.6 线程同步 9.7 在同步方法中使用wait()、notify 和notifyAll()方法 9.8 挂起、恢复和终止线程 ...

    java多线程核心技术

    资深Java专家10年经验总结,全程案例式讲解,首本全面介绍Java多线程编程技术的专著 结合大量实例,全面讲解Java多线程编程中的并发访问、线程间通信、锁等最难突破的核心技术与应用实践 Java多线程无处不在,如...

    java多线程实现大批量数据导入源码

    java多线程实现大批量数据切分成指定份数的数据,然后多线程处理入库或者导出,线程的个数和每份数据的数量都可以控制

    java多线程查询数据库

    java多线程并发查询数据库,使用线程池控制分页,并发查询。

    java多线程模拟队列实现排队叫号

    java多线程模拟队列实现排队叫号,多线程模拟排队叫号取号 java多线程模拟队列实现排队叫号,多线程模拟排队叫号取号

    java多线程进度条

    java多线程进度条

Global site tag (gtag.js) - Google Analytics