设计思路:保证每个线程中共享资源的独立性
ExecutionTask
package com.dwz.concurrency2.chapter11; public class ExecutionTask implements Runnable { private QueryFromDBAction queryaction = new QueryFromDBAction(); private QueryFromHttpAction httpAction = new QueryFromHttpAction(); @Override public void run() { final Context context = new Context(); queryaction.execute(context); System.out.println("The name query successful."); httpAction.execute(context); System.out.println("The card id query successful."); System.out.println("The name is " + context.getName() + " and cardId is " + context.getCardId()); } }
QueryFromDBAction业务逻辑执行者1
package com.dwz.concurrency2.chapter11; public class QueryFromDBAction { public void execute(Context context) { try { Thread.sleep(1000L); String name = "Alex " + Thread.currentThread().getName(); context.setName(name); } catch (InterruptedException e) { e.printStackTrace(); } } }
QueryFromHttpAction业务逻辑执行者2
package com.dwz.concurrency2.chapter11; public class QueryFromHttpAction { public void execute(Context context) { String name = context.getName(); String cardId = getCardId(name); context.setCardId(cardId); } private String getCardId(String name) { try { Thread.sleep(1000L); } catch (InterruptedException e) { e.printStackTrace(); } return "4464643@@" + Thread.currentThread().getId(); } }
Context共享资源
package com.dwz.concurrency2.chapter11; public class Context { private String name; private String cardId; public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void setCardId(String cardId) { this.cardId = cardId; } public String getCardId() { return cardId; } }
测试
package com.dwz.concurrency2.chapter11; import java.util.stream.IntStream; public class ContextTest { public static void main(String[] args) { IntStream.range(1, 5).forEach(i -> new Thread(new ExecutionTask()).start()); } }
使用ThreadLocal来实现线程上下文设计模式,实现线程之间的隔离
ExecutionTask
package com.dwz.concurrency2.chapter12; public class ExecutionTask implements Runnable { private QueryFromDBAction queryaction = new QueryFromDBAction(); private QueryFromHttpAction httpAction = new QueryFromHttpAction(); @Override public void run() { queryaction.execute(); System.out.println("The name query successful."); httpAction.execute(); System.out.println("The card id query successful."); Context context = ActionContext.getActionContext().getContext(); System.out.println("The name is " + context.getName() + " and cardId is " + context.getCardId()); } }
ActionContext聚合ThreadLocal
package com.dwz.concurrency2.chapter12; public class ActionContext { private static final ThreadLocal<Context> threadlocal = new ThreadLocal<Context>() { @Override protected Context initialValue() { return new Context(); }; }; private static class ContextHolder { private static final ActionContext actioncontext = new ActionContext(); } public static ActionContext getActionContext() { return ContextHolder.actioncontext; } public Context getContext() { return threadlocal.get(); } }
Context
package com.dwz.concurrency2.chapter12; public class Context { private String name; private String cardId; public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void setCardId(String cardId) { this.cardId = cardId; } public String getCardId() { return cardId; } }
QueryFromDBAction
package com.dwz.concurrency2.chapter12; public class QueryFromDBAction { public void execute() { try { Thread.sleep(1000L); String name = "Alex " + Thread.currentThread().getName(); ActionContext.getActionContext().getContext().setName(name); } catch (InterruptedException e) { e.printStackTrace(); } } }
QueryFromHttpAction
package com.dwz.concurrency2.chapter12; public class QueryFromHttpAction { public void execute() { Context context = ActionContext.getActionContext().getContext(); String name = context.getName(); String cardId = getCardId(name); context.setCardId(cardId); } private String getCardId(String name) { try { Thread.sleep(1000L); } catch (InterruptedException e) { e.printStackTrace(); } return "4464643@@" + Thread.currentThread().getId(); } }
测试
package com.dwz.concurrency2.chapter12; import java.util.stream.IntStream; public class ContextTest { public static void main(String[] args) { IntStream.range(1, 5).forEach(i -> new Thread(new ExecutionTask()).start()); } }