码迷,mamicode.com
首页 > 编程语言 > 详细

从头认识java-17.2 基本的线程机制(2)-Executors的使用

时间:2016-01-08 17:09:13      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:

在前面的章节我们都是直接对Thread进行管理,我们这里解释一下另一个管理Thread的类Executors。

1.例子:

package com.ray.ch17;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test {

	public static void main(String[] args) throws InterruptedException {
		long startTime = System.currentTimeMillis();
		ExecutorService executorService = Executors.newCachedThreadPool();
		CountDownLatch countDownLatch = new CountDownLatch(5);
		for (int i = 5; i < 10; i++) {
			DoneMission doneMission = new DoneMission(i, countDownLatch);
			executorService.execute(doneMission);
		}
		executorService.shutdown();
		countDownLatch.await();
		long endTime = System.currentTimeMillis();
		System.out.println();
		System.out.println(endTime - startTime);
	}
}

class DoneMission implements Runnable {
	private final int id = index++;
	private int count = 0;
	private static int index = 0;
	private CountDownLatch countDownLatch;

	public DoneMission(int count, CountDownLatch countDownLatch) {
		this.count = count;
		this.countDownLatch = countDownLatch;
	}

	public String leftMission() {
		return "#" + id + "(" + count + ") ";
	}

	@Override
	public void run() {
		while (count-- > 0) {
			System.out.print(leftMission());
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			Thread.yield();
		}
		countDownLatch.countDown();
	}
}


解释:

(1)运行任务的类跟前面的基本一致

(2)使用Executors.newCachedThreadPool()生成线程池,当需要线程驱动的时候,我们可以到里面拿,它生成的线程数是有系统控制的。


2.对线程的数量做出控制

package com.ray.ch17;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test {

	public static void main(String[] args) throws InterruptedException {
		long startTime = System.currentTimeMillis();
		ExecutorService executorService = Executors.newFixedThreadPool(5);//控制线程的数量
		CountDownLatch countDownLatch = new CountDownLatch(5);
		for (int i = 5; i < 10; i++) {
			DoneMission doneMission = new DoneMission(i, countDownLatch);
			executorService.execute(doneMission);
		}
		executorService.shutdown();
		countDownLatch.await();
		long endTime = System.currentTimeMillis();
		System.out.println();
		System.out.println(endTime - startTime);
	}
}

class DoneMission implements Runnable {
	private final int id = index++;
	private int count = 0;
	private static int index = 0;
	private CountDownLatch countDownLatch;

	public DoneMission(int count, CountDownLatch countDownLatch) {
		this.count = count;
		this.countDownLatch = countDownLatch;
	}

	public String leftMission() {
		return "#" + id + "(" + count + ") ";
	}

	@Override
	public void run() {
		while (count-- > 0) {
			System.out.print(leftMission());
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			Thread.yield();
		}
		countDownLatch.countDown();
	}
}

上面的代码只是替换了一句,就可以控制线程的数量,但是我们一般还是建议使用cache的那个,因为它对线程池做出来优化。特别是对于短的异步任务它具有明显优势。


3.测试不同线程运行的时间:

package com.ray.ch17;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test {

	public static void main(String[] args) throws InterruptedException {
		long startTime = System.currentTimeMillis();
		ExecutorService executorService = Executors.newCachedThreadPool();
		CountDownLatch countDownLatch = new CountDownLatch(5);
		for (int i = 5; i < 10; i++) {
			DoneMission doneMission = new DoneMission(i, countDownLatch);
			executorService.execute(doneMission);
		}
		executorService.shutdown();
		countDownLatch.await();
		long endTime = System.currentTimeMillis();
		System.out.println();
		System.out.println("time:"+(endTime - startTime));
	}
}

class DoneMission implements Runnable {
	private final int id = index++;
	private int count = 0;
	private static int index = 0;
	private CountDownLatch countDownLatch;

	public DoneMission(int count, CountDownLatch countDownLatch) {
		this.count = count;
		this.countDownLatch = countDownLatch;
	}

	public String leftMission() {
		return "#" + id + "(" + count + ") ";
	}

	@Override
	public void run() {
		while (count-- > 0) {
			System.out.print(leftMission());
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			Thread.yield();
		}
		countDownLatch.countDown();
	}
}

输出:

#0(4) #1(5) #2(6) #3(7) #4(8) #0(3) #1(4) #4(7) #3(6) #2(5) #0(2) #1(3) #3(5) #2(4) #4(6) #0(1) #1(2) #4(5) #3(4) #2(3) #0(0) #1(1) #2(2) #4(4) #3(3) #1(0) #2(1) #3(2) #4(3) #4(2) #3(1) #2(0) #3(0) #4(1) #4(0) 
904


控制为3个线程:

package com.ray.ch17;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test {

	public static void main(String[] args) throws InterruptedException {
		long startTime = System.currentTimeMillis();
		ExecutorService executorService = Executors.newFixedThreadPool(3);
		CountDownLatch countDownLatch = new CountDownLatch(5);
		for (int i = 5; i < 10; i++) {
			DoneMission doneMission = new DoneMission(i, countDownLatch);
			executorService.execute(doneMission);
		}
		executorService.shutdown();
		countDownLatch.await();
		long endTime = System.currentTimeMillis();
		System.out.println();
		System.out.println(endTime - startTime);
	}
}

class DoneMission implements Runnable {
	private final int id = index++;
	private int count = 0;
	private static int index = 0;
	private CountDownLatch countDownLatch;

	public DoneMission(int count, CountDownLatch countDownLatch) {
		this.count = count;
		this.countDownLatch = countDownLatch;
	}

	public String leftMission() {
		return "#" + id + "(" + count + ") ";
	}

	@Override
	public void run() {
		while (count-- > 0) {
			System.out.print(leftMission());
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			Thread.yield();
		}
		countDownLatch.countDown();
	}
}

输出:

#0(4) #2(6) #1(5) #1(4) #0(3) #2(5) #0(2) #2(4) #1(3) #1(2) #2(3) #0(1) #0(0) #1(1) #2(2) #1(0) #2(1) #3(7) #3(6) #4(8) #2(0) #3(5) #4(7) #3(4) #4(6) #3(3) #4(5) #4(4) #3(2) #4(3) #3(1) #4(2) #3(0) #4(1) #4(0) 
1504


控制为单线程:

package com.ray.ch17;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test {

	public static void main(String[] args) throws InterruptedException {
		long startTime = System.currentTimeMillis();
		ExecutorService executorService = Executors.newSingleThreadExecutor();
		CountDownLatch countDownLatch = new CountDownLatch(5);
		for (int i = 5; i < 10; i++) {
			DoneMission doneMission = new DoneMission(i, countDownLatch);
			executorService.execute(doneMission);
		}
		executorService.shutdown();
		countDownLatch.await();
		long endTime = System.currentTimeMillis();
		System.out.println();
		System.out.println(endTime - startTime);
	}
}

class DoneMission implements Runnable {
	private final int id = index++;
	private int count = 0;
	private static int index = 0;
	private CountDownLatch countDownLatch;

	public DoneMission(int count, CountDownLatch countDownLatch) {
		this.count = count;
		this.countDownLatch = countDownLatch;
	}

	public String leftMission() {
		return "#" + id + "(" + count + ") ";
	}

	@Override
	public void run() {
		while (count-- > 0) {
			System.out.print(leftMission());
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			Thread.yield();
		}
		countDownLatch.countDown();
	}
}

输出:

#0(4) #0(3) #0(2) #0(1) #0(0) #1(5) #1(4) #1(3) #1(2) #1(1) #1(0) #2(6) #2(5) #2(4) #2(3) #2(2) #2(1) #2(0) #3(7) #3(6) #3(5) #3(4) #3(3) #3(2) #3(1) #3(0) #4(8) #4(7) #4(6) #4(5) #4(4) #4(3) #4(2) #4(1) #4(0) 
3503

单线程说白了就像直接在main方法里面使用for来运行的一样。


4.关于shutdown()(下面的这段话摘自http://my.oschina.net/bairrfhoinn/blog/177639,笔者觉得他解释的已经比较清楚,其实关键是笔者比较懒,不喜欢打字)

为了关闭在 ExecutorService 中的线程,你需要调用 shutdown() 方法。ExecutorService 并不会马上关闭,而是不再接收新的任务,一旦所有的线程结束执行当前任务,ExecutorServie 才会真的关闭。所有在调用 shutdown() 方法之前提交到 ExecutorService 的任务都会执行。 
如果你希望立即关闭 ExecutorService,你可以调用 shutdownNow() 方法。这个方法会尝试马上关闭所有正在执行的任务,并且跳过所有已经提交但是还没有运行的任务。但是对于正在执行的任务,是否能够成功关闭它是无法保证的,有可能他们真的被关闭掉了,也有可能它会一直执行到任务结束。


总结:这一章节主要介绍Executors的使用。


这一章节就到这里,谢谢。

-----------------------------------

目录


从头认识java-17.2 基本的线程机制(2)-Executors的使用

标签:

原文地址:http://blog.csdn.net/raylee2007/article/details/50482961

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