码迷,mamicode.com
首页 > 其他好文 > 详细

第21章 并发

时间:2015-07-28 06:35:15      阅读:118      评论:0      收藏:0      [点我收藏+]

标签:

package booknote.chapter21_并发;

/**

 * 一个线程就是在进程中的一个单一的顺序控制流

 * web库的基本类Servlet具有天生的多线程性,因为web服务器经常包含多个处理器,而并发是充分利用这些处理器的理想方式

 */

public class ThreadNote {

/**

 * 定义任务:一个public的内部类

 * 当从Runnable导出一个类时,它必须具有run()方法,但是这个方法并无特殊之处,它不会产生任何内在的线程能力。

 * 要实现线程行为,则必须显示地将一个任务附着到线程上 。

 */

public static class Liftoff implements Runnable{

 

protected int countDown = 10;

private static int taskCount = 0;

private final int id  = taskCount++;

public Liftoff(){

}

public Liftoff(int countDown){

this.countDown = countDown;

}

public String status(){

return "#"+id+"("+ (countDown>0?countDown:"Liftoff!")+")";

}

public void run(){

while(countDown-->0){

System.out.println(status());

/**

 * 对静态方法Thread.yield()的调用时对线程调度器:

 * java线程机制的一部分,可以将cpu从一个线程转移给另一个线程

 * 相当于声明:我已经执行完生命周期中最重要的部分了,此刻正是切换给其他任务执行一段时间的大好时机

 */

Thread.yield();

}

}

}

 

/**

 * 在main()线程中创建新定义的执行任务的线程

 */

public static void main(String[] args) {

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

/**

 * Thread构造器只需要一个Runnable对象。

 * 调用Thread对象的start()方法为该线程执行必需的初始化操作,然后调用Runnable的run()方法,以便在新线程中启动该任务。

 * Start()看起来是产生了一个对长期运行方法的调用,实际上产生的是对Liftoff.run()的方法调用,

 * 就算这个方法还没有完成,但是因为Liftoff.run()是由不同的线程执行的,因此仍旧可以执行main()线程中的其他操作

 * (任何线程都可以启动另一个线程),因此程序看起来会同时运行两个方法main(),Liftoff.run()

 */

/**

 * 当main()创建Thread对象时,它并没有捕获任何对这些对象的引用。

 * 在使用普通对象时,这对于垃圾回收来说是一场公平游戏,但是使用Thread时,情况会不同。

 * 每个Thred都"注册了自己,因此确实有一个对它的引用,而且在它的任务退出其run()并死亡之前,垃圾回收器无法清除它。

 * 因此,一个线程会创建一个单独的执行线程,在对start()的调用完成之后,它仍旧会继续存在。" 

 */

new Thread(new Liftoff()).start();

System.out.println("waiting for liftoff!");

}

}

}

 

 

package booknote.chapter21_并发;

 

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

 

import booknote.chapter21_并发.ThreadNote.Liftoff;

 

/**

 * JAVA SE5的java.util.concurrent包中的执行器Executor用来管理Thread对象,从而简化并发编程。

 * Executor在客户端和任务执行之间提供了一个间接层;与客户端直接执行任务不同,这个中介对象将执行任务。

 * Executor允许你管理异步任务的执行,而无须显示地管理线程的生命周期。

 */

public class CachedThreadPool {

 

public static void main(String[] args) {

//ExecutorService对象是使用静态的Executor方法创建,这个方法可以确定其Executor类型

ExecutorService exec =Executors.newCachedThreadPool();

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

exec.execute(new Liftoff());

}

exec.shutdown();

 

 

/**

 * FixedThreadPool使用有限的线程集来执行所提交的任务,即一次性预先执行代价高昂的线程分配,因而就可以限制线程的数量了。

 * 这样可以节省时间,因为你不用为每个任务都固定地付出创建线程的开销。

 * 注意:在任何线程池中,现有线程在可能的情况下,都会被自动复用。

 * 

 * CachedThreadPool在程序执行过程中通常会创建与所需数量相同的线程,然后在它回收旧线程时停止创建新线程,因此它是合理的

 * Executor的首选。只有当这种方式会引发问题时,你才需要切换到FixedThreadPool

 */

ExecutorService exec2 =Executors.newFixedThreadPool(5);

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

exec2.execute(new Liftoff());

}

exec2.shutdown();

 

 

 

 

}

 

}

 

 

第21章 并发

标签:

原文地址:http://www.cnblogs.com/aries1991/p/4681662.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!