java线程安全理解

如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
比如一个 ArrayList 类,在添加一个元素的时候,它可能会有两步来完成:1. 在 Items[Size] 的位置存放此元素;2. 增大 Size 的值。

  在单线程运行的情况下,如果 Size = 0,添加一个元素后,此元素在位置 0,而且 Size=1;

  而如果是在多线程情况下,比如有两个线程,线程 A 先将元素存放在位置 0。但是此时 CPU 调度线程A暂停,线程 B 得到运行的机会。线程B也向此 ArrayList 添加元素,因为此时 Size 仍然等于 0 (注意哦,我们假设的是添加一个元素是要两个步骤哦,而线程A仅仅完成了步骤1),所以线程B也将元素存放在位置0。然后线程A和线程B都继续运行,都增加 Size 的值。

  那好,现在我们来看看 ArrayList 的情况,元素实际上只有一个,存放在位置 0,而 Size 却等于 2。这就是“线程不安全”了。
如何做到线程安全:
四种方式   sychronized关键字

1. sychronized method(){}

2. sychronized (objectReference) {/*block*/}

3. static synchronized method(){}

4. sychronized(classname.class)

其中1和2是代表锁当前对象,即一个对象就一个锁,3和4代表锁这个类,即这个类的锁。要注意的是sychronized method()不是锁这个函数,而是锁对象,即:如果这个类中有两个方法都是sychronized,那么只要有两个线程共享一个该类的reference,每个调用这两个方法之一,不管是否同一个方法,都会用这个对象锁进行同步。
   注意:long 和double是简单类型中两个特殊的咚咚:java读他们要读两次,所以需要同步。

java线程安全理解的更多相关文章

  1. java线程的理解

    java thread类都是native方法实现的,所以没有用平台无关的方法实现,怎么实现的呢? 线程的实现: 第一种:使用内核线程实现. 内核线程就是直接使用操作系统内核支持的线程,由内核完成切换. ...

  2. Java线程池理解及用法

    前言 多线程的异步执行方式,虽然能够最大限度发挥多核计算机的计算能力,但是如果不加控制,反而会对系统造成负担.线程本身也要占用内存空间,大量的线程会占用内存资源并且可能会导致Out of Memory ...

  3. Java线程中断理解(interrupte)

    Java线程之中,一个线程的生命周期分为:初始.就绪.运行.阻塞以及结束.当然,其中也可以有四种状态,初始.就绪.运行以及结束. 一般而言,可能有三种原因引起阻塞:等待阻塞.同步阻塞以及其他阻塞(睡眠 ...

  4. 【转】关于Java的Daemon线程的理解

    原文地址:http://www.cnblogs.com/ChrisWang/archive/2009/11/28/1612815.html 关于Java的Daemon线程的理解 网上对Java的Dae ...

  5. Java线程锁&分布式锁的理解及应用

    了解Java线程锁之前,先理解线程和进程的定义.进程是操作系统分配资源(CPU)的基本单位,线程是CPU执行的基本单位,一个进程可拥有多个线程,同进程间的多个线程共享分配给进程的资源.比如启动JVM时 ...

  6. 深入理解Java线程池:ScheduledThreadPoolExecutor

    介绍 自JDK1.5开始,JDK提供了ScheduledThreadPoolExecutor类来支持周期性任务的调度.在这之前的实现需要依靠Timer和TimerTask或者其它第三方工具来完成.但T ...

  7. Java线程工作内存与主内存变量交换过程及volatile关键字理解

    Java线程工作内存与主内存变量交换过程及volatile关键字理解 1. Java内存模型规定在多线程情况下,线程操作主内存变量,需要通过线程独有的工作内存拷贝主内存变量副本来进行.此处的所谓内存模 ...

  8. 2018.7.26 进程和线程的区别 &&你对 Java平台的理解

    进程和线程的区别 1.定义 进程:具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程:进程的一个实体,是CPU调度和分派的基本单位,它是比进程更 ...

  9. 干货,阿里P8浅谈对java线程池的理解(面试必备)

    线程池的概念 线程池由任务队列和工作线程组成,它可以重用线程来避免线程创建的开销,在任务过多时通过排队避免创建过多线程来减少系统资源消耗和竞争,确保任务有序完成:ThreadPoolExecutor ...

随机推荐

  1. [工作积累] NDK通过Java获取package name 和version

    ////////////////////////////////////////////////////////////////////////// //Java code snippet //get ...

  2. Ubuntu下配置Docbook环境

    1.准备环境 $sudo apt-get install xsltproc $sudo apt-get install docbook-xsl $sudo apt-get install docboo ...

  3. Asp.net的服务器推技术 (Server Push)

    在以往的和服务器端通信技术中,我们多数使用的是AJAX轮询式访问,也就是在Javascript中控制时间间隔,然后每隔一段时间就访问一次服务器,然后获得数据或通知.但是这种轮询方式的访问有90%是在做 ...

  4. C#[Serializable]在C#中的作用-NET 中的对象序列化

    为什么要使用序列化?最重要的两个原因是:将对象的状态保存在存储媒体中以便可以在以后重新创建出完全相同的副本:按值将对象从一个应用程序域发送至另一个应用程序域.例如,序列化可用于在 ASP.NET 中保 ...

  5. 禁用backspace键的后退功能

    禁用backspace键的后退功能,但是可以删除文本内容<script language="JavaScript">document.onkeydown = check ...

  6. webservice wsdl 生成服务

    由于之前的示例是在当前项目下发布的server,也是在当前项目下访问的server发布的webservice.但在实际应用中,我们的服务端往往是和客户諯分离的,甚至它们是不同的项目中不同的人写的.而像 ...

  7. 几种基于HTTP协议的RPC性能比较

    有了整体的了解后,可以发现Hessian的这个远程过程调用,完全使用动态代理来实现的,其实从客户端代码不难看出,HessianProxyFactory的create方法就是创建接口Basic的代理类, ...

  8. unity android 集成指南

    原地址:http://blog.csdn.net/alking_sun/article/details/36175187 1.安卓层开发并暴露接口.   launcher activity(以下称为U ...

  9. ubuntu修改ip、网关、dns等

    一.使用命令设置Ubuntu IP地址 1.修改配置文件blacklist.conf禁用IPV6 sudo vi /etc/modprobe.d/blacklist.conf 表示用vi编辑器(也可以 ...

  10. codeforces 455B A Lot of Games(博弈,字典树)

    题目 参考自博客:http://blog.csdn.net/keshuai19940722/article/details/38455269 //字典树,博弈 根据当前节点的后续来确定当前节点的状态, ...