Java多线程相关知识【17】--设计模式--上下文模式(Context)
文章目录
- Java多线程相关知识【17】--设计模式--上下文模式(Context)
- 1. 问题的引入
- 2. 解决方法
- 1. 解决理论
- 2. 实操代码
- 上下文数据保存
- 上文
- 下文
- 调度者
- 测试上下文
- 3. 优雅的解决方法
- 1. 问题的发现
- 2. 解决原理
- 3. 实操代码
- 上下文数据保存
- 上下文数据保存单例
- 上文
- 下文
- 调度者
- 运行测试
菜鸟的一个学习笔记,欢迎大神 批评指正。
Java多线程相关知识【17】–设计模式–上下文模式(Context)
1. 问题的引入
线程在操作数据时,有很多时候要继续上一次操作的数据后才能进行本次的处理,为了解决这种办法,我们需要将一定的数据进行封装,在进行下次的处理,这既是上下文的处理模式。
2. 解决方法
1. 解决理论
将相应的数据进行封装,然后进行相关的操作即可实现代码的利于维护性。
2. 实操代码
上下文数据保存
/*** 上下文数据保存*/
public class Context {private String first;private String second;public String getFirst() {return first;}public void setFirst(String first) {this.first = first;}public String getSecond() {return second;}public void setSecond(String second) {this.second = second;}
}
上文
/*** 第一次查询*/
public class FirstAction {private final String s="The first task:";public String exude(String key) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}return s+key;}
}
下文
/*** 连续查询*/
public class SecondAction {private final String s="The second task:(";/*** 使用上一次结果查询本次内容* @param firstResult 上一次的结果* @return 查询的结果*/public String exude(String firstResult){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}return s+firstResult+")";}
}
调度者
/*** 调度*/
public class Working implements Runnable {private final FirstAction firstAction = new FirstAction();private final SecondAction secondAction= new SecondAction();@Overridepublic void run() {Context context =new Context();//上文context.setFirst(firstAction.exude("666"));System.out.println("First successful!");System.out.println(context.getFirst());context.setSecond(secondAction.exude(context.getFirst()));System.out.println("Second successful!");System.out.println(context.getSecond());}
}
测试上下文
/*** 执行测试*/
public class ContextTest {public static void main(String[] args) {IntStream.range(0,5).forEach(value -> new Thread(new Working()).start());}
}
3. 优雅的解决方法
1. 问题的发现
由于上边的例子采用了一个参数进行相互的上下文操作,若进行了多个参数进行操作,将导致代码的繁杂度更大。那么如何解决这个问题呢?
2. 解决原理
利用ThreadLocal即可减少变量的设置操作。
3. 实操代码
上下文数据保存
/*** 上下文数据保存*/
public class Context {private String first;private String second;public String getFirst() {return first;}public void setFirst(String first) {this.first = first;}public String getSecond() {return second;}public void setSecond(String second) {this.second = second;}
}
上下文数据保存单例
/*** 上下文数据保存单例,且使用ThreadLocal*/
public class ActionContext {private static final ThreadLocal<Context> threadLocal = ThreadLocal.withInitial(() -> new Context());private ActionContext() {}private enum ActionContextHoder {INSTANCE;private ActionContext context;ActionContextHoder() {context = new ActionContext();}public ActionContext getContext() {return context;}}public static ActionContext getActionContext() {return ActionContextHoder.INSTANCE.getContext();}public static ThreadLocal<Context> getThreadLocal() {return threadLocal;}public Context getContext() {return threadLocal.get();}}
上文
/*** 第一次查询改进*/
public class FirstActionImp {private final String s="The first task:";public void exude(String key) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}ActionContext.getActionContext().getContext().setFirst(s+key);}
}
下文
/*** 连续查询*/
public class SecondActionImp {private final String s = "The second task:(";/*** 使用上一次结果查询本次内容** @return 查询的结果*/public void exude() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}ActionContext.getActionContext().getContext().setSecond(s+ActionContext.getActionContext().getContext().getFirst()+")");}
}
调度者
/*** 调度*/
public class WorkingImp implements Runnable {private final FirstActionImp firstActionImp = new FirstActionImp();private final SecondActionImp secondActionImp= new SecondActionImp();@Overridepublic void run() {//上文ActionContext actionContext=ActionContext.getActionContext();firstActionImp.exude("666");System.out.println("First successful!");System.out.println(actionContext.getContext().getFirst());secondActionImp.exude();System.out.println("Second successful!");System.out.println(actionContext.getContext().getSecond());}
}
运行测试
/*** 执行测试*/
public class ContextTest {public static void main(String[] args) {IntStream.range(0,5).forEach(value -> new Thread(new Working()).start());}
}
Java多线程相关知识【17】--设计模式--上下文模式(Context)相关推荐
- Java多线程相关知识
1)wait() notify() sleep() sleep是Thread类的函数,wait和notify是Object的函数. sleep的时候keep对象锁,wait的时候release 对 ...
- Java多线程相关的几十个问题
转载来源:http://www.cnblogs.com/HadesFX/p/5333810.html , https://www.cnblogs.com/HadesFX/p/5333820.html ...
- Java并发相关知识(多线程、锁、容器、工具)
目录 一.基础知识 线程之间如何通信? Java内存模型 内存屏障 顺序一致性 CAS实现原理 原子操作 volatile synchronized 实现原理 什么是锁 原子操作类说明 高性能原子类 ...
- java线程知识梳理_Java多线程——多线程相关知识的逻辑关系梳理
1 学习多线程知识的根本目标 多线程知识的根本目标是:设计稳健的并发程序. 当然,本文无法回答这个实践性很强的问题(这与具体的业务相关,涉及到具体的策略),本文主要阐述相关知识之间的关系,希望初学者不 ...
- Java多线程编程实战指南+设计模式篇pdf
下载地址:网盘下载 随着CPU 多核时代的到来,多线程编程在充分利用计算资源.提高软件服务质量方面扮演了越来越重要的角色.而 解决多线程编程中频繁出现的普遍问题可以借鉴设计模式所提供的现成解决方案.然 ...
- Java多线程基础知识
多线程基础知识 这是我再次学习多线程知识的一个总结,对于刚刚接触的学习者是比较友好易懂的,便于快速的理解和掌握. 一.基本概念: 1.进程:进程就是运行中的程序,当一个程序开始执行,操作系统就会给这个 ...
- Java多线程核心知识
多线程相对于其他 Java 知识点来讲,有一定的学习门槛,并且了解起来比较费劲.在平时工作中如若使用不当会出现数据错乱.执行效率低(还不如单线程去运行)或者死锁程序挂掉等等问题,所以掌握了解多线程至关 ...
- Java多线程基础知识(一)
Java多线程 一.Java线程模型 实现线程有三种方式:使用内核线程实现.使用用户线程实现和使用用户线程加轻量级进程混合实现.内核线程是直接由操作系统内核支持的线程,通过内核完成线程切换,内核通过操 ...
- java字符串相关知识
文章目录 1 基本知识 1.1 String是否是基本类型? 1.2 创建String的方式 1.3 String.StringBuilder.StringBuffer之间的关系 2 常用工具类 2. ...
最新文章
- Windows8.1+Eclipse搭建Hadoop2.7.2本地模式开发环境
- pytorch 对特征进行mean_Pytorch的mean和std调查实例
- usb驱动---linux ACM驱动详解ACA【转】
- android布局置顶_android linearlayout imageview置顶摆放
- Android IPC —— AIDL的原理
- 软件测试初学者如何编写Jmeter测试脚本?
- 微信小程序开发实战第六讲之手机号验证码登录
- 专升本英语——菜鸟学习笔记【知识点齐全-轻松学习】!!!
- SD/SDHC/SDXC区别
- VBA实现为Excel中自定义名称的单元格添加批注
- python广义极值_广义极值(GEV)极大似然拟合的奇异pdf
- 组件化拆分(三)-Todos案例——单页面-详细代码
- 金蝶K3WISE常用数据表
- 迅雷影音tv版 v5.1.1.3091 官方版
- word复制到另一个文档,endnotes出现乱码处理
- 小程序云开发修改他人数据问题
- Linux使用nexus搭建maven私服
- 携程:春节出境游搜索量成倍飙升,新加坡、韩国、中国香港、日本和泰国成为最受欢迎的出境目的地 | 美通社头条...
- 产品经理核心思维—FABE销售法
- SpringMVC系列之基本配置