Java并发编程核心方法与框架-Executors的使用
2017-01-09 14:07
507 查看
合理利用线程池能够带来三个好处
降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
官方建议使用Executors工厂类来创建线程池对象
使用newCachedThreadPool()方法创建无界线程池
使用Executors类的newCachedThreadPool()方法创建的是无界线程池,可以进行线程自动回收。所谓的“无界线程池”就是池中存放线程个数理论上是Integer.MAX_VALUE。
程序运行结果如下:
线程池的线程复用效果
程序运行结果如下:
由打印结果可见,第一次for循环中创建了5个线程对象分别是pool-1-thread-1到pool-1-thread-5,第二次for循环中没有创建新的线程对象,复用了第一次for循环中创建的线程对象。
使用newCachedThreadPool(ThreadFactory)定制线程工厂
程序运行结果如下:
使用newFixedThreadPool(int)方法创建有界线程池
程序运行结果如下:
此时线程池中最多有三个线程。
使用newFixedThreadPool(int, ThreadFactory)定制线程工厂
程序运行结果如下:
使用newSingleThreadExecutor()方法创建单一线程池
程序运行结果如下:
此时线程池中只有一个线程。
newSingleThreadExecutor(ThreadFactory) 使用方法与前面的大体一致。
降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
官方建议使用Executors工厂类来创建线程池对象
使用newCachedThreadPool()方法创建无界线程池
使用Executors类的newCachedThreadPool()方法创建的是无界线程池,可以进行线程自动回收。所谓的“无界线程池”就是池中存放线程个数理论上是Integer.MAX_VALUE。
public class Run1 { public static void main(String[] args) { ExecutorService executorService = Executors.newCachedThreadPool(); executorService.execute(new Runnable() { @Override public void run() { try { System.out.println("Runnable1 begin:" + System.currentTimeMillis()); Thread.sleep(1000); System.out.println("A"); System.out.println("Runnable1 end:" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } } }); executorService.execute(new Runnable() { @Override public void run() { try { System.out.println("Runnable2 begin:" + System.currentTimeMillis()); Thread.sleep(1000); System.out.println("A"); System.out.println("Runnable2 end:" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } } }); } }
程序运行结果如下:
Runnable1 begin:1470228063076 Runnable2 begin:1470228063076 A A Runnable2 end:1470228064081 Runnable1 end:1470228064081
线程池的线程复用效果
public class MyRunnable implements Runnable { private String username; public MyRunnable(String username) { super(); this.username = username; } @Override public void run() { System.out.println(Thread.currentThread().getName() + " username=" + username + " begin:" + System.currentTimeMillis()); System.out.println(Thread.currentThread().getName() + " username=" + username + " end:" + System.currentTimeMillis()); } } public class Main { public static void main(String[] args) throws InterruptedException { ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0; i < 5; i++) { executorService.execute(new MyRunnable("" + i)); } Thread.sleep(2000); System.out.println(); for (int i = 0; i < 5; i++) { executorService.execute(new MyRunnable("" + i)); } } }
程序运行结果如下:
pool-1-thread-1 username=0 begin:1470229448635 pool-1-thread-4 username=3 begin:1470229448635 pool-1-thread-3 username=2 begin:1470229448635 pool-1-thread-2 username=1 begin:1470229448635 pool-1-thread-3 username=2 end:1470229448635 pool-1-thread-4 username=3 end:1470229448635 pool-1-thread-5 username=4 begin:1470229448635 pool-1-thread-1 username=0 end:1470229448635 pool-1-thread-5 username=4 end:1470229448636 pool-1-thread-2 username=1 end:1470229448635 pool-1-thread-1 username=2 begin:1470229450637 pool-1-thread-3 username=4 begin:1470229450637 pool-1-thread-3 username=4 end:1470229450637 pool-1-thread-2 username=0 begin:1470229450637 pool-1-thread-2 username=0 end:1470229450638 pool-1-thread-5 username=1 begin:1470229450637 pool-1-thread-4 username=3 begin:1470229450637 pool-1-thread-4 username=3 end:1470229450638 pool-1-thread-5 username=1 end:1470229450638 pool-1-thread-1 username=2 end:1470229450637
由打印结果可见,第一次for循环中创建了5个线程对象分别是pool-1-thread-1到pool-1-thread-5,第二次for循环中没有创建新的线程对象,复用了第一次for循环中创建的线程对象。
使用newCachedThreadPool(ThreadFactory)定制线程工厂
public class MyThreadFactory implements ThreadFactory { @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setName("定制池中线程对象的名称" + Math.random()); return thread; } } public class Run { public static void main(String[] args) { MyThreadFactory myThreadFactory = new MyThreadFactory(); ExecutorService executorService = Executors.newCachedThreadPool(myThreadFactory); executorService.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "运行:" + System.currentTimeMillis()); } }); } }
程序运行结果如下:
定制池中线程对象的名称0.2671917944865071运行:1470230269473
使用newFixedThreadPool(int)方法创建有界线程池
public class MyRunnable implements Runnable { String username; public MyRunnable(String username) { super(); this.username = username; } @Override public void run() { try { System.out.println(Thread.currentThread().getName() + " username=" + username + " begin:" + System.currentTimeMillis()); Thread.sleep(2000); System.out.println(Thread.currentThread().getName() + " username=" + username + " end:" + System.currentTimeMillis()); } catch (Exception e) { e.printStackTrace(); } } } public class Run { public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(3); for (int i = 0; i < 3; i++) { executorService.execute(new MyRunnable("" + i)); } for (int i = 0; i < 3; i++) { executorService.execute(new MyRunnable("" + i)); } } }
程序运行结果如下:
pool-1-thread-1 username=0 begin:1470230865037 pool-1-thread-3 username=2 begin:1470230865037 pool-1-thread-2 username=1 begin:1470230865037 pool-1-thread-3 username=2 end:1470230867043 pool-1-thread-1 username=0 end:1470230867042 pool-1-thread-3 username=0 begin:1470230867043 pool-1-thread-1 username=1 begin:1470230867043 pool-1-thread-2 username=1 end:1470230867043 pool-1-thread-2 username=2 begin:1470230867043 pool-1-thread-3 username=0 end:1470230869047 pool-1-thread-1 username=1 end:1470230869047 pool-1-thread-2 username=2 end:1470230869047
此时线程池中最多有三个线程。
使用newFixedThreadPool(int, ThreadFactory)定制线程工厂
public class MyThreadFactory implements ThreadFactory { @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setName("定制池中线程对象的名称" + Math.random()); return thread; } } public class Run { public static void main(String[] args) { MyThreadFactory threadFactory = new MyThreadFactory(); ExecutorService executorService = Executors.newFixedThreadPool(2, threadFactory); Runnable runnable = new Runnable() { @Override public void run() { try { System.out.println("begin 我在运行" + System.currentTimeMillis() + " " + Thread.currentThread().getName()); Thread.sleep(2000); System.out.println("end 我在运行" + System.currentTimeMillis() + " " + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } }; executorService.execute(runnable); executorService.execute(runnable); executorService.execute(runnable); } }
程序运行结果如下:
begin 我在运行1470231214770 定制池中线程对象的名称0.07643716796315236 begin 我在运行1470231214770 定制池中线程对象的名称0.5060032203497645 end 我在运行1470231216773 定制池中线程对象的名称0.5060032203497645 end 我在运行1470231216773 定制池中线程对象的名称0.07643716796315236 begin 我在运行1470231216773 定制池中线程对象的名称0.5060032203497645 end 我在运行1470231218774 定制池中线程对象的名称0.5060032203497645
使用newSingleThreadExecutor()方法创建单一线程池
public class MyRunnable implements Runnable { String username; public MyRunnable(String username) { super(); this.username = username; } @Override public void run() { try { System.out.println(Thread.currentThread().getName() + " username=" + username + " begin:" + System.currentTimeMillis()); Thread.sleep(2000); System.out.println(Thread.currentThread().getName() + " username=" + username + " end:" + System.currentTimeMillis()); } catch (Exception e) { e.printStackTrace(); } } } public class Run { public static void main(String[] args) { ExecutorService executorService = Executors.newSingleThreadExecutor(); for (int i = 0; i < 3; i++) { executorService.execute(new MyRunnable("" + i)); } } }
程序运行结果如下:
pool-1-thread-1 username=0 begin:1470231470978 pool-1-thread-1 username=0 end:1470231472978 pool-1-thread-1 username=1 begin:1470231472978 pool-1-thread-1 username=1 end:1470231474982 pool-1-thread-1 username=2 begin:1470231474982 pool-1-thread-1 username=2 end:1470231476984
此时线程池中只有一个线程。
newSingleThreadExecutor(ThreadFactory) 使用方法与前面的大体一致。
相关文章推荐
- Java并发编程核心方法与框架-Executors的使用
- Java并发编程核心方法与框架-TheadPoolExecutor的使用
- Java并发编程核心方法与框架-ExecutorService的使用
- Java并发编程核心方法与框架-Semaphore的使用
- Java并发编程核心方法与框架-Future和Callable的使用
- Java并发编程核心方法与框架-phaser的使用
- Java并发编程核心方法与框架-CyclicBarrier的使用
- Java并发编程核心方法与框架-ScheduledExecutorService的使用
- Java并发编程核心方法与框架-CompletionService的使用
- Java并发编程核心方法与框架-TheadPoolExecutor的使用
- Java并发编程核心方法与框架-ScheduledExecutorService的使用
- Java并发编程核心方法与框架-CountDownLatch的使用
- Java并发编程核心方法与框架-ExecutorService的使用
- Java并发编程核心方法与框架-phaser的使用
- Java并发编程核心方法与框架-exchanger的使用
- Java并发编程核心方法与框架-Semaphore的使用
- Java并发编程核心方法与框架-CountDownLatch的使用
- Java并发编程核心方法与框架-CyclicBarrier的使用
- Java并发编程核心方法与框架-CompletionService的使用
- Java并发编程核心方法与框架-Fork-Join分治编程(二)