Java并发编程——线程安全及解决机制简介
简介:
本文主要介绍了Java多线程环境下,可能会出现的问题(线程不安全)以及相应的解决措施。通过本文,你将学习到如下几块知识:
1. 为什么需要多线程(多线程的优势)
1. 多线程带来的问题—线程安全
2. 产生线程不安全的原因
3. 有哪些方法能解决线程不安全
------------------------------------------------------------
系好安全带,下面进入正文:
一:为什么需要多线程?
线程是Java语言中不可或缺的重要部分,它们能使复杂的异步代码变得简单,简化复杂系统的开发;能充分发挥多处理器系统的强大计算能力。多线程和多进程的区别与选择可以参考我的另一篇博客。
(1) 优点
1. 充分利用硬件资源。由于线程是cpu的基本调度单位,所以如果是单线程,那么最多只能同时在一个处理器上运行,意味着其他的CPU资源都将被浪费。而多线程可以同时在多个处理器上运行,只要各个线程间的通信设计正确,那么多线程将能充分利用处理器的资源。
2. 结构优雅。多线程程序能将代码量巨大,复杂的程序分成一个个简单的功能模块,每块实现复杂程序的一部分单一功能,这将会使得程序的建模,测试更加方便,结构更加清晰,更加优雅。
3. 简化异步处理。为了避免阻塞,单线程应用程序必须使用非阻塞I/O,这样的I/O复杂性远远高于同步I/O,并且容易出错。
(2) 缺点
1. 线程安全:由于统一进程下的多个线程是共享同样的地址空间和数据的,又由于线程执行顺序的不可预知性,一个线程可能会修改其他线程正在使用的变量,这一方面是给数据共享带来了便利;另一方面,如果处理不当,会产生脏读,幻读等问题,好在Java提供了一系列的同步机制来帮助解决这一问题,例如内置锁。
2. 活跃性问题。可能会发生长时间的等待锁,甚至是死锁。
3. 性能问题。 线程的频繁调度切换会浪费资源,同步机制会导致内存缓冲区的数据无效,以及增加同步流量。
二:线程安全
(1) 定义:当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替运行,并且在主调试代码中不需要任何额外的同步或者协同,这个类都能表现出正确的行为,则称这个类时线程安全的。线程安全类中封装了必要的同步机制,因此客户端无须进一步采取同步措施。
(2) 线程安全产生的原因:正确性取决于多个线程的交替执行时序,产生了竞态条件。
(3) 原子类: 应尽量使用原子类,这样会让你分析线程安全时更加方便,但需要注意的是用线程安全类构建的类并不能保证线程安全。例如,一个AtomicInteger get() 和 AtomicInteger set() 是线程安全的,在一个类的一个方法 f()中同时用到了这两个方法,此时的f()就是线程不安全的,因为你不能保证这个复合操作中的get 和 set同时更新。
三:解决机制
1. 加锁。
(1) 锁能使其保护的代码以串行的形式来访问,当给一个复合操作加锁后,能使其成为原子操作。一种错误的思想是只要对写数据的方法加锁,其实这是错的,对数据进行操作的所有方法都需加锁,不管是读还是写。
(2) 加锁时需要考虑性能问题,不能总是一味地给整个方法加锁synchronized就了事了,应该将方法中不影响共享状态且执行时间比较长的代码分离出去。
(3) 加锁的含义不仅仅局限于互斥,还包括可见性。为了确保所有线程都能看见最新值,读操作和写操作必须使用同样的锁对象。
2. 不共享状态
(1) 无状态对象: 无状态对象一定是线程安全的,因为不会影响到其他线程。
(2) 线程关闭: 仅在单线程环境下使用。
3. 不可变对象
可以使用final修饰的对象保证线程安全,由于final修饰的引用型变量(除String外)不可变是指引用不可变,但其指向的对象是可变的,所以此类必须安全发布,也即不能对外提供可以修改final对象的接口。
Java并发编程——线程安全及解决机制简介的更多相关文章
- Java并发编程实战 05等待-通知机制和活跃性问题
Java并发编程系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 Java并发编程实 ...
- Java 并发编程 | 线程池详解
原文: https://chenmingyu.top/concurrent-threadpool/ 线程池 线程池用来处理异步任务或者并发执行的任务 优点: 重复利用已创建的线程,减少创建和销毁线程造 ...
- java并发编程 线程基础
java并发编程 线程基础 1. java中的多线程 java是天生多线程的,可以通过启动一个main方法,查看main方法启动的同时有多少线程同时启动 public class OnlyMain { ...
- 《Java并发编程实战》读书笔记一 -- 简介
<Java并发编程实战>读书笔记一 -- 简介 并发的历史 并发的历史,也是人类利用有限的资源去提高生产效率的一个的例子. 设想现在有台计算机,这台计算机具有以下的资源: 单核CPU一个 ...
- java并发编程 | 线程详解
个人网站:https://chenmingyu.top/concurrent-thread/ 进程与线程 进程:操作系统在运行一个程序的时候就会为其创建一个进程(比如一个java程序),进程是资源分配 ...
- Java并发编程实战 02Java如何解决可见性和有序性问题
摘要 在上一篇文章当中,讲到了CPU缓存导致可见性.线程切换导致了原子性.编译优化导致了有序性问题.那么这篇文章就先解决其中的可见性和有序性问题,引出了今天的主角:Java内存模型(面试并发的时候会经 ...
- Java并发编程:线程间通信wait、notify
Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...
- Java并发编程:线程和进程的创建(转)
Java并发编程:如何创建线程? 在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识, ...
- Java并发编程的本质是解决这三大问题
[本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究.若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!] 前言 并发编程的 ...
随机推荐
- WLAN高密无线网络部署的信道问题
WIFI信号的信道有两部分,其中2.4G频段有13个左右交叠的信道(14信道只在日本使用),其中只能找出3个相互不重合的信道(具体请参考文末的链接),最常用的就是1.6.11这三个,当然也可以使用其他 ...
- Safari Private 模式下 localStorage 的问题
现如今好多浏览器都有「隐身模式」,Safari 管这叫「Private Browing」,国内各种牌子的套壳浏览器叫「无痕浏览」.私以为从命名上来说,倒是国内更中文一些. 这种模式下浏览网页踏雪无痕, ...
- 摘记:Web应用系统测试内容
表示层: 内容测试,包括整体审美.字体.色彩.拼写.内容准确性和默认值 Web站点结构,包括无效的链接或图形 用户环境,包括Web浏览器版本和操作系统配置(每一个浏览器都有不同的脚本引擎或虚拟机在客户 ...
- PC版模块滚动不显示滚动条效果
以前对某个模块增加无滚动条的滚动效果,还需要找个插件才能实现,现在发现个简单方法,用普通的CSS就可以实现. 此方法只适用于不显示滚动条的滚动效果,如果需要自定义滚动条样式,还是需要插件来实现. HT ...
- [HNOI2009]梦幻布丁 算法技巧之邻接链
题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入输出格式 输入格式: 第 ...
- 简单总结下关于blob的图片上传
我是从一本书上看到了Azure Blob,然后在网上浪了一会儿,发现了这篇文章,里面他已经把重点的则重地方讲完了,"飞机票:http://www.cnblogs.com/sparkdev/p ...
- Could not open input file: composer.phar
Yii 2官网推荐用Composer安装框架,但是在本地出错:Could not open input file: composer.phar.后来修改了命令行就ok了,难道是我装的Composer跟 ...
- vue setTimeout用法 jquery滚动到某一个div的底部
//vue 中setTimeOut用法 var $this = this; setTimeout(function(){ $this.goEnd() }, 10); goEnd:function(){ ...
- php后台拼接输出table表格
<?php header("Content-type:text/html;charset=utf-8"); $str=''; $str.='<table border= ...
- 【LeetCode】94. Binary Tree Inorder Traversal
题目: Given a binary tree, return the inorder traversal of its nodes' values. For example:Given binary ...