zoukankan      html  css  js  c++  java
  • 从头认识java-18.2 主要的线程机制(2)-Executors的使用

    在前面的章节我们都是直接对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的使用。


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

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

    文件夹


  • 相关阅读:
    javascript重点笔记
    我的CSS架构
    排行榜妙用——CSS计数器
    回归基础从新认识——HTML+CSS
    前端开发工具(安装及常用技巧)——sublime text 3
    手机访问php环境移动端静态页面
    H5前端面试题及答案(2)
    H5前端面试题及答案(1)
    python笔记--学会使用Fiddler
    python进程/线程/协成
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/7285676.html
Copyright © 2011-2022 走看看