`
臻是二哥
  • 浏览: 189180 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
博客专栏
Group-logo
Java技术分享
浏览量:0
社区版块
存档分类
最新评论

JAVA并发-并发编程概述

阅读更多
不知道各位童鞋是否干过在程序主进程中嵌入IO操作这样“任性”的事情,笔者曾经干过,而且那时候还觉得自己很棒。没办法,那时候还年轻啊。后来随着学习的深入,知道了有nio这种神一样的东西。但如果有其他方案,至少笔者是不会使用nio这个类的。毕竟程序的易读性还是很重要滴。多数时候,我们完全可以使用多线程和IO阻塞来代替非阻塞IO。
最近读了下经典《Java并发编程实践》,大师的书的确很棒,好了不说废话了,来写下我的笔记吧。
并发编程主要需要解决安全性,活跃性和性能的问题。下面是个人的理解:
1 安全性:程序可以确定的按照我们希望的时序执行。
2 活跃性:程序最终会输出正确的结果
3 性能:程序多长时间能输出正确的结果。
对于程序设计人员,我们需要在上面的3点之间寻找一种平衡,一种在满足安全性基础之上的平衡。
首先,我觉得有一个问题需要解决,那就是什么时候使用并发编程:并发编程一定是在需要的时候使用,什么是需要的时候?比如有一天,你的leader和你说,系统太慢了,以至于用户都快跑光了(哈哈,有点夸张),这个时候你就需要考虑一下是否可以使用多线程来做点什么。如果你确实发现了代码中有太多可以用多线程提升的地方,那么,。just do it。否则,还是不要轻易改变了,毕竟“稳定压倒一切吗”。先保证稳定在考虑性能。
当决定使用多线程的时候,我们就需要考虑安全性,活跃性以及性能了。
所谓的安全性,就是要求我们能够编写线程安全的代码,他的核心在于处理那些可以被多个线程共享的可变的变量。就像我在黑体部分说的,需要考虑线程安全的情况,一定是有下列3个条件:
1 一个可以被多个线程访问的变量
2 这个变量是共享的
3 这个变量的值是可以改变的
但你的程序中出现了这3个情况的时候,那么要小心了,需要考虑线程安全问题了。说白了,就是对于这个共享变量的访问时候的同步问题。就是常见的“读-改-写”和“核对后执行”情况。
比如我写了一个类:
@UnThreadSafe
class MyThread extends Thread
{
private int count=0;
public void run(){
count++;
System.out.println("counter="+count);
}
}

在这个例子中,MyThread类的变量count是可以被多个线程访问的,是共享的,是可变的(瞧,满足3个条件),我们需要考虑线程安全问题了。这是一个典型的“读-改-写”的问题,理论上我当然希望每个线程都能一口气执行完count++这条语句,但事实常常不是这样,可能thread-1刚刚读取到count为0,CPU就调度给了thread-2,这个时候thread-2读取到的count也是0,很显然,程序没有按照我们希望的时序执行,我们说他是不安全的。
我们可以使用线面的方式来让他变成线程安全的.
@ThreadSafe
class MyThread extends Thread
{
private final AtomicLong count=new AtomicLong(0);
public void run(){
int tmp=count.incrementAndGet();
System.out.println("counter="+tmp);
}
}

但是有些时候,并不总是有这样的第三方的类可以给我们使用的。

可能我们写了一个类,来根据一个请求的1-9的阿拉伯数字返回对应的大写汉字
public class MyServlet implements Servlet
{
   public void service(ServletRequest req,ServletResponse res){
   int i=getNum(req);
   String str=getHanziByNum(i);
   responseHanzi(res,i);
}
}

尽管service方法被多个线程执行,但不存在安全性的问题(没有多个线程共享的变量);这个时候,如果为了提高性能,需要将上一次请求的数据存储起来,我们来看:
@UnThreadSafe
public class MyServlet implements Servlet
{
private int num;
private String str;
   public void service(ServletRequest req,ServletResponse res){
   int i=getNum(req);
if(i==num)
   responseHanzi(res,str);
else
   String str1=getHanziByNum(i);
   num=i;
   str=str1;
   responseHanzi(res,str1);
}
}

在上面的代码中,出现了多个线程可以访问可变的的共享变量num和str,这时候需要考虑线程安全的问题了。有个最简单的方案将他变为线程安全的:
@ThreadSafe
public class MyServlet implements Servlet
{
private int num;
private String str;
   public synchronized void service(ServletRequest req,ServletResponse res){
   int i=getNum(req);
if(i==num)
   responseHanzi(res,str);
else
   String str1=getHanziByNum(i);
   num=i;
   str=str1;
   responseHanzi(res,str1);
}
}

程序设计人员不去具体分析哪些代码是需要同步的,而是同步一个大的区域,讲所有共享变量圈在里面,当然这样做实现了线程安全。但是没有考虑性能的问题。假设getHanziByNum()是一个非常耗时间的操作,那么同步方法service的执行时间将会非常慢,而整个方法有事同步的,很可能我们的并发代码 运行的性能比串行的还要差(创建和销毁线程需要时间,尽管很短)。因此,我们需要一些更加细粒度的同步,而不是像上面的粗粒度的同步。
@ThreadSafe
public class MyServlet implements Servlet
{
private int num;
private String str;
   public void service(ServletRequest req,ServletResponse res){
   int i=getNum(req);
   String str1=null;
   synchronized(this){
       if(i==num)
         str1=str;
   }
   if(str1=null){
       str1=getHanziByNum(i); 
       synchronized(this){
         num=i;
         str=str1;
       }
   }
   responseHanzi(res,str1);

}
}


上面的类是线程安全的,显然他比之前一个在性能上会更有优势。所以在解决多线程安全性的问题上,关于同步的粒度的大小需要我们仔细的研究,力度大一点可能实现起来简单,但是性能不一定太好。粒度太小的话,可能实现起来难度大,容易出错,怎么做到合适,需要我们自己权衡。

这个时候,如果我还想保存命中的变量
@ThreadSafe
public class MyServlet implements Servlet
{
private int num;
private String str;
private int hits;
private int totalHits;
   public synchronized double getHitRadio{
       return hits/totalHits;
   }   

   public void service(ServletRequest req,ServletResponse res){
   int i=getNum(req);
   String str1=null;
   synchronized(this){
       totalHits++;
       if(i==num){
         str1=str;
         hits++;
       }
   }
   if(str1=null){
       str1=getHanziByNum(i); 
       synchronized(this){
         num=i;
         str=str1;
       }
   }
   responseHanzi(res,str1);

}
}

可以看到,所有共享变量出现的地方都被加了锁(即同步操作),只不过同步的力度不同罢了。
综上所述,关于并发,我们的思路大概是这样的:
1 是否使用并发
2 如果使用用并发,哪些共享变量需要考虑安全性
3 对于需要考虑安全性的那些共享变量,要记得为每一个加锁
4 加锁的粒度粗细的权衡

0
3
分享到:
评论

相关推荐

    Java-美妆神域_3rm1m18i_221-wx.zip

    Java-美妆神域_3rm1m18i_221-wx.zip

    51单片机的温度监测与控制(温控风扇)

    51单片机的温度监测与控制(温控风扇)

    电赛案例,C++简单的智能家居系统,其中包含了温度监测、光照控制和报警系

    电赛案例,C++简单的智能家居系统,其中包含了温度监测、光照控制和报警系统。该系统可以: 监控室内温度:当温度超过设定阈值时,触发警报。 自动调节光照:根据光线传感器的值自动调节LED灯的亮度。 入侵检测:通过红外传感器检测入侵,并触发警报。

    圣诞树 html版 可修改祝福语

    圣诞树 html版 可修改祝福语。 记事本或vscode编辑html文件:ctrl+F寻找”myLabels“关键词,定位到该处即可修改祝福语

    基于python编写的selenium自动化测试框架,采用PO模式,页面元素采用yaml进行管理资料齐全+详细文档+高分项目+源码.zip

    【资源说明】 基于python编写的selenium自动化测试框架,采用PO模式,页面元素采用yaml进行管理资料齐全+详细文档+高分项目+源码.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

    屏幕截图 2024-12-21 170434.png

    屏幕截图 2024-12-21 170434

    基于SpringBoot的学生信息管理系统源码

    基于SpringBoot的学生信息管理系统(前后端源码+数据库+文档+运行截图) 学生信息管理 班级信息管理 教师信息管理 课程信息管理 选课信息管理 考勤信息管理 请假信息管理 成绩信息管理 基于SpringBoot的学生信息管理系统(前后端源码+数据库+文档+运行截图) 学生信息管理 班级信息管理 教师信息管理 课程信息管理 选课信息管理 考勤信息管理 请假信息管理 成绩信息管理基于SpringBoot的学生信息管理系统(前后端源码+数据库+文档+运行截图) 学生信息管理 班级信息管理 教师信息管理 课程信息管理 选课信息管理 考勤信息管理 请假信息管理 成绩信息管理基于SpringBoot的学生信息管理系统(前后端源码+数据库+文档+运行截图) 学生信息管理 班级信息管理 教师信息管理 课程信息管理 选课信息管理 考勤信息管理 请假信息管理 成绩信息管理基于SpringBoot的学生信息管理系统(前后端源码+数据库+文档+运行截图) 学生信息管理 班级信息管理 教师信息管理 课程信息管理 选课信息管理 考勤信息管理

    径向基函数内核 – 机器学习python案例脚本,内核在将数据转换为更高维空间方面发挥着重要作用

    径向基函数内核 – 机器学习 内核在将数据转换为更高维空间方面发挥着重要作用,使算法能够学习复杂的模式和关系。在众多的内核函数中,径向基函数(RBF)内核作为一种多功能且强大的工具脱颖而出。在本文中,我们深入探讨了RBF内核的复杂性,探讨了它的数学公式、直观理解、实际应用及其在各种机器学习算法中的重要性。

    工具变量-中国省级数字经济发展水平面板数据(2012-2022).xlsx

    详细介绍及样例数据:https://blog.csdn.net/samLi0620/article/details/144636765

    51单片机控制的智能小车.7z

    51单片机控制的智能小车.7z

    基于卷积神经网络的数字手势识别安卓APP,识别数字手势0-10详细文档+全部资料+优秀项目+源码.zip

    【资源说明】 基于卷积神经网络的数字手势识别安卓APP,识别数字手势0-10详细文档+全部资料+优秀项目+源码.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

    pymssql-2.1.4.dev5-cp37-cp37m-win-amd64.whl pymssql-2.1.4.dev5-cp37-cp37m-win32.whl

    python 使用sqlserver必须要这个问题,没办法,只能满世界的找地方下载,终于让我下载到了,现在分享给大家使用

    四川采矿场生产安全事故管理制度.docx

    四川采矿场生产安全事故管理制度

    简约灰粉共存版_8.0.53.apk

    简约灰粉共存版_8.0.53.apk

    ECharts散点图-全国主要城市空气质量(百度地图).rar

    ECharts散点图-全国主要城市空气质量(百度地图)

    四川采矿场安全检查管理规定.docx

    四川采矿场安全检查管理规定

    JSP基于WEB网上论坛设计与实现(源代码+论文+开题报告+答辩PPT+外文翻译)(2024kt).7z

    1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于计算机科学与技术等相关专业,更为适合;

    空中俯视物体检测9-YOLOv5数据集合集.rar

    空中俯视物体检测9-YOLOv5数据集合集.rar使用YOLO算法从图像中检测对象-V2 2023-05-11 2:51 PM ============================= *与您的团队在计算机视觉项目上合作 *收集和组织图像 *了解和搜索非结构化图像数据 *注释,创建数据集 *导出,训练和部署计算机视觉模型 *使用主动学习随着时间的推移改善数据集 对于最先进的计算机视觉培训笔记本,您可以与此数据集一起使用 该数据集包括1015张图像。 以YOLO V5 PYTORCH格式注释检测对象 - 图像。 将以下预处理应用于每个图像: *像素数据的自动取向(带有Exif-Arientation剥离) *调整大小为640x640(拉伸) 没有应用图像增强技术。

    会使用到的js文件词云图

    词云图

    Python&OpenCV手势识别系统(完整源码&自定义UI操作界面&视频教程)

    Python高分毕设——Python&Opencv手势识别系统(完整源码&自定义UI操作界面&视频教程) Python高分毕设——Python&Opencv手势识别系统(完整源码&自定义UI操作界面&视频教程) 使用了OpenCV的视频采集, 图像色域转换, 颜色通道分割, 高斯滤波, OSTU自动阈值, 凸点检测, 边缘检测, 余弦定理计算手势等功能. 准备工作 安装 Python-OpenCV 库 pip install opencv-python -i https://mirrors.ustc.edu.cn/pypi/web/simple 利用 -i 为pip指令镜像源, 这里使用电子科技大学的源, 速度比官方源更快. 安装 Numpy 科学计算库 pip install numpy -i https://mirrors.ustc.edu.cn/pypi/web/simple 安装 PyAutogui 库 pip install pyautogui -i https://mirrors.ustc.edu.cn/pypi/web/simple 代码实现 import nu

Global site tag (gtag.js) - Google Analytics