异步线程编程,线程池,线程组,后面涉及ThreadLocal在理解
join模拟订单
package com.future.demo.future; /** * * * @author Administrator * */ public class NormalThreadTest { public static void main(String[] args) throws Exception { long start = System.currentTimeMillis(); // 开启购买厨具线程 ShoppingThread shopping = new ShoppingThread(); shopping.start(); shopping.join(); // 保障厨具购买并送货 // 获取到购买厨具 KitchenWare kc = shopping.kc; // 买食材 FoodMaterial fm = new FoodMaterial(); Thread.sleep(2000); System.out.println("第二步: 食材已经到位"); // 烹饪美食 cooking(kc, fm); System.out.println("第三步: 美食烹饪完成"); long end = System.currentTimeMillis(); System.out.println("烹饪美食时间为:" + (end - start)); } /** * 定义网上购物厨具线程 * @author Administrator * */ static class ShoppingThread extends Thread { // 厨具对象引用 private KitchenWare kc; @Override public void run() { System.out.println("第一步: 网上下单"); System.out.println("第一步: 等待厨具"); try { Thread.sleep(5000); // 等待厨具时间 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("第一步: 快递送货"); // 生产厨具 kc = new KitchenWare(); } } /** * 厨具类 * @author Administrator * */ static class KitchenWare { } /** * 食材类 * @author Administrator * */ static class FoodMaterial { } /** * 定义烹饪食物的方法 * @param kc * @param fm */ static void cooking(KitchenWare kc, FoodMaterial fm) { } }
异步进行
package com.future.demo.future; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; /** * 异步: 同时进行 * 同步: 排队进行 * @author Administrator * */ public class FutureThreadTest { public static void main(String[] args) throws Exception { long start = System.currentTimeMillis(); Callable<KitchenWare> callable = new Callable<KitchenWare>() { public KitchenWare call() throws Exception { System.out.println("第一步: 网上下单"); System.out.println("第一步: 等待厨具"); try { Thread.sleep(5000); // 等待厨具时间 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("第一步: 快递送货"); return new KitchenWare(); } }; // 包装为异步执行的对象 FutureTask<KitchenWare> task = new FutureTask<>(callable); new Thread(task).start(); // 买食材 FoodMaterial fm = new FoodMaterial(); Thread.sleep(2000); System.out.println("第二步: 食材已经到位"); if (!task.isDone()) { System.out.println("厨具还没有到....."); } // 通过阻塞形式获取到异步块执行的结果 KitchenWare kc = task.get(); // 阻塞 // 烹饪美食 cooking(kc, fm); System.out.println("第三步: 美食烹饪完成"); long end = System.currentTimeMillis(); System.out.println("烹饪美食时间为:" + (end - start)); } /** * 厨具类 * @author Administrator * */ static class KitchenWare { } /** * 食材类 * @author Administrator * */ static class FoodMaterial { } /** * 定义烹饪食物的方法 * @param kc * @param fm */ static void cooking(KitchenWare kc, FoodMaterial fm) { } }
线程池
ThreadPoolExecutor
package com.future.demo.threadPool; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * ThreadPoolExecutor * int corePoolSize 线程总数 <= 最大线程数 * int maximumPoolSize 最大线程数 * long keepAliveTime 存活时间 * TimeUnit unit 时间单位 (纳秒,毫秒,秒,分钟,....) * BlockingQueue<Runnable> workQueue 阻塞队列 * @author Administrator * */ public class ThreadPoolExecutorTest { public static void main(String[] args) { // 20来源: 最大线程数 + 阻塞数目 ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 30, 2000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10)); for ( int i = 0; i < 40; i++) { executor.execute(new MyRunnable()); System.out.println("线程池中线程数目:" + executor.getPoolSize() + ",队列中等待执行的任务数目:" + executor.getQueue().size() + ",任务总数目:" + executor.getTaskCount()); } // 防止线程溢出(执行完成的线程会被及时关闭) executor.shutdownNow(); } static class MyRunnable implements Runnable { public void run() { String threadName = Thread.currentThread().getName(); System.out.println(threadName+ "准备执行......"); /*try { // jdk1.5 之后官方推荐使用此方法睡眠 TimeUnit.MILLISECONDS.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); }*/ System.out.println(threadName+"执行完成......"); } } }
SingleThreadExecutor
package com.future.demo.threadPool; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 创建一个单线程的线程池。这个线程池只有一个线程在工作, * 也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束, * 那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。 * @author Administrator * */ public class SingleThreadExecutorTest { public static void main(String[] args) { MyThread t1 = new MyThread("AAA"); MyThread t2 = new MyThread("BBB"); MyThread t3 = new MyThread("CCC"); MyThread t4 = new MyThread("DDD"); ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); // 保证在线程池中的线程执行的顺序 singleThreadExecutor.execute(t4); singleThreadExecutor.execute(t1); singleThreadExecutor.execute(t2); singleThreadExecutor.execute(t3); singleThreadExecutor.shutdown(); } } class MyThread extends Thread { private String name; public MyThread(String name) { super(name); this.name = name; } @Override public void run() { System.out.println(name+"执行"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }
FixedThreadExecutor
package com.future.demo.threadPool; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。 * 线程池的大小一旦达到最大值就会保持不变, * 如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。 * @author Administrator * */ public class FixedThreadExecutorTest { public static void main(String[] args) { MyThread t1 = new MyThread("AAA"); MyThread t2 = new MyThread("BBB"); MyThread t3 = new MyThread("CCC"); MyThread t4 = new MyThread("DDD"); ExecutorService singleThreadExecutor = Executors.newFixedThreadPool(2); singleThreadExecutor.execute(t1); singleThreadExecutor.execute(t2); singleThreadExecutor.execute(t3); singleThreadExecutor.execute(t4); singleThreadExecutor.shutdown(); } }
CacheThreadExecutor
package com.future.demo.threadPool; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程, 那么就会回收部分空闲(60秒不执行任务)的线程, 当任务数增加时,此线程池又可以智能的添加新线程来处理任务。 此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小 * @author Administrator * */ public class CacheThreadExecutorTest { public static void main(String[] args) { MyThread t1 = new MyThread("AAA"); MyThread t2 = new MyThread("BBB"); MyThread t3 = new MyThread("CCC"); MyThread t4 = new MyThread("DDD"); ExecutorService singleThreadExecutor = Executors.newCachedThreadPool(); singleThreadExecutor.execute(t1); singleThreadExecutor.execute(t2); singleThreadExecutor.execute(t3); singleThreadExecutor.execute(t4); singleThreadExecutor.shutdown(); } }
ScheduledThreadExecutor
package com.future.demo.threadPool; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; /*** * 创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。 * @author Administrator * */ public class ScheduledThreadExecutorTest { public static void main(String[] args) { ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(2); exec.scheduleAtFixedRate(new Runnable() {// 每隔一段时间就触发异常 @Override public void run() { System.out.println("================"); } }, 1, 1, TimeUnit.SECONDS); exec.scheduleAtFixedRate(new Runnable() {// 每隔一段时间打印系统时间,证明两者是互不影响的 public void run() { System.out.println(System.nanoTime()); } }, 1, 100, TimeUnit.MILLISECONDS); } }
线程组
ThreadGroup
package com.future.demo.threadgroup; public class ThreadGroupTest { public static void main(String[] args) throws Exception { ThreadGroup group = new ThreadGroup("main Thread"); Thread t1 = new Thread(group,"AAA") { @Override public void run() { while(true) { System.out.println(Thread.currentThread().getName()+"执行"); } } }; Thread t2 = new Thread(group,"BBB") { @Override public void run() { while(true) { System.out.println(Thread.currentThread().getName()+"执行"); } } }; t1.start(); t2.start(); Thread.sleep(5000); System.out.println(Thread.currentThread().getThreadGroup().activeCount()); group.list(); } }
package com.future.demo.conn; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReentrantLock; public class NormalConnectionPool { private Map<String, Connection> connPool = new HashMap<String, Connection>(); private ReentrantLock lock = new ReentrantLock(); public Connection getConnection(String key) { Connection conn = null; try { lock.lock(); if (connPool.containsKey(key)) { conn = connPool.get(key); } else { // 创建连接对象 conn = crateConn(); connPool.put(key, conn); } } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } return conn; } private Connection crateConn() { return new Connection(); } public static void main(String[] args) throws Exception { NormalConnectionPool pool = new NormalConnectionPool(); long start = System.currentTimeMillis(); Thread t1 = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 200000; i++) { Connection conn = pool.getConnection("KK"); System.out.println("KK-----"+conn); } } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 200000; i++) { Connection conn = pool.getConnection("YY"); System.out.println("YY-----"+conn); } } }); Thread t3 = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 200000; i++) { Connection conn = pool.getConnection("FF"); System.out.println("FF-----"+conn); } } }); t1.start();t2.start();t3.start(); t1.join();t2.join();t3.join(); long end = System.currentTimeMillis(); System.out.println(end - start); } } class Connection { }
package com.future.demo.conn; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class SuperConnectionPool { private ConcurrentHashMap<String, FutureTask<Connection>> connPool = new ConcurrentHashMap<>(); public Connection getConnection(String key) { Connection conn = null; FutureTask<Connection> connectionTask = connPool.get(key); if (connectionTask != null) { try { conn = connectionTask.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } else { Callable<Connection> callable = new Callable<Connection>() { @Override public Connection call() throws Exception { return new Connection(); } }; FutureTask<Connection> newTask = new FutureTask<>(callable); connPool.putIfAbsent(key, newTask); if (connectionTask == null) { connectionTask = newTask; connectionTask.run(); } } try { conn = connectionTask.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } return conn; } public static void main(String[] args) throws InterruptedException { SuperConnectionPool pool = new SuperConnectionPool(); long start = System.currentTimeMillis(); Thread t1 = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 200000; i++) { Connection conn = pool.getConnection("KK"); System.out.println("KK-----"+conn); } } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 200000; i++) { Connection conn = pool.getConnection("YY"); System.out.println("YY-----"+conn); } } }); Thread t3 = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 200000; i++) { Connection conn = pool.getConnection("FF"); System.out.println("FF-----"+conn); } } }); t1.start();t2.start();t3.start(); t1.join();t2.join();t3.join(); long end = System.currentTimeMillis(); System.out.println(end - start); } }