一.一个实现了Runnable接口的类

class MyThread implements Runnable{
private static int num = 0;
@Override
public void run() {
while(true){
synchronized(MyThread.class){
++num;
try{
Thread.sleep(500);
} catch(Exception e){
System.out.println(e.toString());
}
System.out.println(Thread.currentThread().getName() + " " + num);
}
}
}
}

1. newCachedThreadPool()方法

  CacheThreadPool会为每一个任务创建一个线程。非常常见的情况是,单个的Executor被用来创建和管理系统中的任务。shutdown()方法可以防止新的任务被提交给这个Executor。如果在shutdown()方法之后提交新任务,则会抛出java.util.concurrent.RejectedExecutionException异常。

public class Main{
public static void main(String[] args){
ExecutorService exes = Executors.newCachedThreadPool();
for(int i=0; i<5; ++i)
exes.execute(new MyThread());
exes.shutdown();
}
}

2.FixedThreadPool()方法

  FixedThreadPool使用了优先的线程集来执行所提交的任务。有了它,你就可以一次性预先执行代价高的线程分配。也就是说如果设置的最大线程数量是x,而提交的线程数y,那么(y-x)对应的这些线程要等到前x个线程执行完毕才会执行。

  下面的例子中,线程6一直不会有机会执行。因为run()方法中是 while(true), 可以将while(true)去掉,前5个线程执行完毕后,才会执行第6个线程。

public class Main{
public static void main(String[] args){
ExecutorService exes = Executors.newFixedThreadPool(5);
for(int i=0; i<6; ++i)
exes.execute(new MyThread());
exes.shutdown();
}
}

3.newSingleThreadExecutor()方法

public class Main{
public static void main(String[] args){
ExecutorService exes = Executors.newSingleThreadExecutor();
for(int i=0; i<5; ++i)
exes.execute(new MyThread());
exes.shutdown();
}

  SingleThreadExecutor就像是线程数量为1的FixedThreadPool。这对于你希望在另一个线程中连续运行的事物(长期存活的任务)来说,都是很有用的。如果想SingleThreadExecutor提交了多个任务,那么这些任务将排队,每个任务都会在下一个任务开始之前结束,所有的任务将使用相同的线程。

二.一个实现了Callable<E>接口的类(从任务中产生返回值)

class MyThread implements Callable<String>{
private static int num = 0;
@Override
public String call() throws Exception {
for(int i=0; i<5; ++i){
synchronized(MyThread.class){
++num;
Thread.sleep(200);
System.out.println(Thread.currentThread().getName() + " " + num);
}
}
return Thread.currentThread().getName() + " success!";
}
}

1.ExecutorService.submit()方法

public class Main{
public static void main(String[] args){
ExecutorService exes = Executors.newCachedThreadPool();
ArrayList<Future<String>> rets = new ArrayList<Future<String>>();
for(int i=0; i<5; ++i)
rets.add(exes.submit(new MyThread()));
for(Future<String> fs : rets){
try {
System.out.println(fs.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}

  submit()会产生Future对象,它用Callable返回结果的特定类型进行了参数化。可以调用Future的isDone()方法来查询Future是否已经完成。调用Future的get()方法来获取最终线程的执行结果。另外,Future的get()方法是一个阻塞方法,直到结果准备就绪。

三.线程的优先级

class MyThread implements Runnable{
private int priority;
public MyThread(){
} public MyThread(int priority){
this.priority = priority;
} private static int num = 0;
private volatile double d;
@Override
public void run() {
Thread.currentThread().setPriority(priority);
while(true){
for(int i=0; i<100000; ++i){
d += (Math.PI+Math.E)/(double)i;
if(i%1000 == 0)
Thread.yield();
}
synchronized(MyThread.class){
++num;
try{
Thread.sleep(500);
} catch(Exception e){
System.out.println(e.toString());
}
System.out.println(Thread.currentThread().getName() + " " + num);
}
}
}
} public class Main{
public static void main(String[] args){
ExecutorService exes = Executors.newCachedThreadPool();
for(int i=0; i<5; ++i)
exes.execute(new MyThread(Thread.MIN_PRIORITY));
exes.execute(new MyThread(Thread.MAX_PRIORITY));
exes.shutdown();
}
}

  volatile变量保证编译器对循环不进行任何的优化,如果不加入这些运算的话,就不会看到设置线程优先级的效果。数学运算是可以中断的,向控制台打印不能被中断。这里预案算时间足够的长,因此线程调度机制才来的及介入,交换任务并关注优先级,是的最高优先级被优先选择。

四.后台线程

class SimpleDaemons implements Runnable{
@Override
public void run() {
while(true){
try{
TimeUnit.MILLISECONDS.sleep(200);
System.out.println(Thread.currentThread().getName());
} catch(InterruptedException e){
System.out.println(Thread.currentThread().getName() + " : InterruptException!");
e.printStackTrace();
}
}
}
} public class Main{
public static void main(String[] args) throws InterruptedException{
for(int i=0; i<10; ++i){
Thread daemon = new Thread(new SimpleDaemons());
daemon.setDaemon(true);
daemon.start();
}
System.out.println("All daemons started");
TimeUnit.MILLISECONDS.sleep(1000);
}
}

  所谓后台线程,是指程序运行的时候在后台提供一种通用的服务的线程,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非后台线程结束时,程序也就终止了,同时会杀死进程中的所有的后台线程。反过来说,只要任何非后台线程还在运行,程序就不会终止。

  通过定制自己的ThreadFactory, 可以定制有Executor创建的线程的属性(后台,优先级,名称)

class DaemonThreadFactory implements ThreadFactory{
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
}
class DaemonFromFactory implements Runnable{
@Override
public void run() {
try{
TimeUnit.MILLISECONDS.sleep(100);
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e){
e.printStackTrace();
}
}
} public class Main{
public static void main(String[] args) throws InterruptedException{
ExecutorService exes = Executors.newCachedThreadPool(new DaemonThreadFactory());
for(int i=0; i<5; ++i)
exes.execute(new DaemonFromFactory());
System.out.println("All Daemos Started!");
TimeUnit.MILLISECONDS.sleep(1000);
}
}

java使用Executor(执行器)管理线程的更多相关文章

  1. Java的Executor框架和线程池实现原理

    Java的Executor框架 1,Executor接口 public interface Executor { void execute(Runnable command); } Executor接 ...

  2. java笔记--用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程

    用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程 ThreadLocal在我的笔记"关于线程同步"的第5种方式里面有介绍,这里就不多说了. ...

  3. Java的Executor框架和线程池实现原理(转)

    ExecutorService接口继承自Executor接口,定义了终止.提交,执行任务.跟踪任务返回结果等方法 1,execute(Runnable command):履行Ruannable类型的任 ...

  4. 使用Executor管理线程

    上一篇博客(第一个并发程序:定义任务和驱动任务)中,我们使用Thread对象启动线程,而java.util.concurrent包的Executor执行器提供了更好的管理Thread对象的方法,从而简 ...

  5. Java多线程——<三>简单的线程执行:Executor

    一.概述 按照<Java多线程——<一><二>>中所讲,我们要使用线程,目前都是显示的声明Thread,并调用其start()方法.多线程并行,明显我们需要声明多个 ...

  6. java并发编程(十七)Executor框架和线程池

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17465497   Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动 ...

  7. 转:【Java并发编程】之十九:并发新特性—Executor框架与线程池(含代码)

      Executor框架简介 在Java5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java.util.coc ...

  8. Java 并发编程——Executor框架和线程池原理

    Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相当于生产者,执行任务 ...

  9. 【Java并发编程】:并发新特性—Executor框架与线程池

    Executor框架简介 在Java5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java.util.cocur ...

随机推荐

  1. windows 10 开始菜单和cortana无法工作的问题

    过了个周末,到了实验室一开机发现报了个关键错误:开始菜单和cortana无法工作. 经过一番google ,发现问题,原来是360禁用了一个服务导致,这个服务是UserManager. 我直接去开启发 ...

  2. Redis_密码管理(转)

    一. 如何初始化redis的密码? 总共2个步骤: a.在配置文件中有个参数: requirepass  这个就是配置redis访问密码的参数. 比如 requirepass test123 b.配置 ...

  3. Docker中images无法使用apt-get update解决方案

    问题描述:使用apt-get update一直fail 原因:DNS设置错误 解决办法: nm-tool #查看DNS后面的数(IPv4),将后面的数copy下来 sudo nano /etc/def ...

  4. 快速定位性能瓶颈,检查出所有资源(CPU、内存、磁盘IO等)的利用率(utilization)、饱和度(saturation)和错误(error)度量,即USE方法

    命令:uptime说明:查看机器分别在1分钟.5分钟.15分钟的平均负载情况,显示的数字表示等待cpu资源的进程和阻塞在不可中断io进程的数量,如果1分钟的平均负载很高,而15分钟的平均负载很低,说明 ...

  5. USACO翻译:USACO 2014 FEB SILVER 三题

    USACO 2014 FEB SILVER 一.题目概览 中文题目名称 自动打字 路障 神秘代码 英文题目名称 auto rblock scode 可执行文件名 auto rblock scode 输 ...

  6. Android课程---关于Service的学习(后台运行)

    MainActivity.java package com.hanqi.test2; import android.content.ComponentName; import android.cont ...

  7. window.location.href 中文乱码问题。。。。

    window.location.href 中文乱码问题.... 要解决此问题需要两次解码, 第一次解码: 是在页面中的js脚本中解码:window.location.href = "save ...

  8. PHP Strict Standards:问题解决

    异常信息: ( ! ) Strict standards: Declaration of SugarEmailAddress::save() should be compatible with tha ...

  9. ASP.NET Web API 接口执行时间监控

    软件产品常常会出现这样的情况:产品性能因某些无法预料的瓶颈而受到干扰,导致程序的处理效率降低,性能得不到充分的发挥.如何快速有效地找到软件产品的性能瓶颈,则是我们感兴趣的内容之一. 在本文中,我将解释 ...

  10. java中文乱码解决之道(八)-----解决URL中文乱码问题

    我们主要通过两种形式提交向服务器发送请求:URL.表单.而表单形式一般都不会出现乱码问题,乱码问题主要是在URL上面.通过前面几篇博客的介绍我们知道URL向服务器发送请求编码过程实在是实在太混乱了.不 ...