实例讲解Java并发编程之变量

编写线程安全需要关心的:

1.共享的变量
2.可变的变量

共享意味着多个线程可以同时访问,可变意味着其值在生命周期可以改变。
例如以下count 变量:

代码如下:

//线程不安全的类
public class UnsafeCount {
    private int count = 0;    //该变量是共享的
    public void increase() {    //这里没有同步机制,多个线程可以同时访问
        count++;    //该变量是可变的
    }
    public int getCount() {
        return count;
    }
}

有4种方式可以修复这个问题:

1.不在线程中共享该状态变量,可以将变量封装到方法中(无状态的对象一定是线程安全的);因为方法中变量是每个线程独占的,不和其它线程共享。比如:

代码如下:

public int add(int count){
return ++count;//这里也可以说无状态的对象一定是线程安全的
}

2.将状态变量修改为不可变的变量。

代码如下:

private final  int count = 0;

3.在访问状态变量使用同步策略。

代码如下:

public synchronized  void increase() {
count++;
}

4.使用原子变量类。

代码如下:

private AtomicInteger count;
 public void increase() {
  count.getAndAdd(1);
 }

(0)

相关推荐

  • Java并发编程之创建线程

    先讲述一下Java中的应用程序和进程相关的概念知识,然后再阐述如何创建线程以及如何创建进程.下面是本文的目录大纲: 一.Java中关于应用程序和进程相关的概念 二.Java中如何创建线程 三.Java中如何创建进程 一.Java中关于应用程序和进程相关的概念 在Java中,一个应用程序对应着一个JVM实例(也有地方称为JVM进程),一般来说名字默认为java.exe或者javaw.exe(windows下可以通过任务管理器查看).Java采用的是单线程编程模型,即在我们自己的程序中如果没有主动创

  • Java并发编程示例(一):线程的创建和执行

    开门见山 在IT圈里,每当我们谈论并发时,必定会说起在一台计算机上同时运行的一系列线程.如果这台电脑上有多个处理器或者是一个多核处理器,那么这时是实实在在的"同时运行":但是,如果计算机只有一个单核处理器,那么这时的"同时运行"只是表象而已. 所有的现代操作系统全部支持任务的并发执行.你可以边听音乐,边上网看新闻,还不耽误首发电子邮件.我们可以说,这种并发是 进程级并发 .在进程内部,我也可以看到有许许多多的并发任务.我们把运行在一个进程里面的并发任务称 线程. 和

  • Java 线程池详解及创建简单实例

    Java 线程池 最近在改进项目的并发功能,但开发起来磕磕碰碰的.看了好多资料,总算加深了认识.于是打算配合查看源代码,总结并发编程的原理. 准备从用得最多的线程池开始,围绕创建.执行.关闭认识线程池整个生命周期的实现原理.后续再研究原子变量.并发容器.阻塞队列.同步工具.锁等等主题.java.util.concurrent里的并发工具用起来不难,但不能仅仅会用,我们要read the fucking source code,哈哈.顺便说声,我用的JDK是1.8. Executor框架 Exec

  • java并发编程_线程池的使用方法(详解)

    一.任务和执行策略之间的隐性耦合 Executor可以将任务的提交和任务的执行策略解耦 只有任务是同类型的且执行时间差别不大,才能发挥最大性能,否则,如将一些耗时长的任务和耗时短的任务放在一个线程池,除非线程池很大,否则会造成死锁等问题 1.线程饥饿死锁 类似于:将两个任务提交给一个单线程池,且两个任务之间相互依赖,一个任务等待另一个任务,则会发生死锁:表现为池不够 定义:某个任务必须等待池中其他任务的运行结果,有可能发生饥饿死锁 2.线程池大小 注意:线程池的大小还受其他的限制,如其他资源池:

  • 实例讲解Java并发编程之变量

    编写线程安全需要关心的: 1.共享的变量 2.可变的变量 共享意味着多个线程可以同时访问,可变意味着其值在生命周期可以改变. 例如以下count 变量: 复制代码 代码如下: //线程不安全的类 public class UnsafeCount {     private int count = 0;    //该变量是共享的     public void increase() {    //这里没有同步机制,多个线程可以同时访问         count++;    //该变量是可变的  

  • 实例讲解Java并发编程之闭锁

    闭锁相当于一扇门,在闭锁到达结束状态之前,这扇门一直是关闭着的,没有任何线程可以通过,当到达结束状态时,这扇门才会打开并容许所有线程通过.它可以使一个或多个线程等待一组事件发生.闭锁状态包括一个计数器,初始化为一个正式,正数表示需要等待的事件数量.countDown方法递减计数器,表示一个事件已经发生,而await方法等待计数器到达0,表示等待的事件已经发生.CountDownLatch强调的是一个线程(或多个)需要等待另外的n个线程干完某件事情之后才能继续执行. 场景应用: 10个运动员准备赛

  • 实例讲解Java设计模式编程中的OCP开闭原则

    定义:一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 问题由来:在软件的生命周期内,因为变化.升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试. 解决方案:当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化.          开闭原则是面向对象设计中最基础的设计原则,它指导我们如何建立稳定灵活的系统.开闭原则可能是设计模式六项原则中定义最模糊的一个了,它

  • 实例讲解Java并发编程之ThreadLocal类

    ThreadLocal类可以理解为ThreadLocalVariable(线程局部变量),提供了get与set等访问接口或方法,这些方法为每个使用该变量的线程都存有一份独立的副本,因此get总是返回当前执行线程在调用set时设置的最新值.可以将ThreadLocal<T>视为 包含了Map<Thread,T>对象,保存了特定于该线程的值. 概括起来说,对于多线程资源共享的问题,同步机制采用了"以时间换空间"的方式,而ThreadLocal采用了"以空间

  • 实例讲解Java设计模式编程中如何运用代理模式

    定义:  Provide a surrogate or placeholder for another object to control access to it. 为其他对象一种代理以控制对这个对象的访问. 一般描述: 一般包含的三个角色:抽象主题.具体主题.代理主题. 抽象主题:是一个抽象类或接口,是一个普通的业务类型定义. 具体主题:业务逻辑的具体执行者 代理角色:负责对真是角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现. 通用类图: 通用代码: package Pro

  • java并发编程专题(八)----(JUC)实例讲解CountDownLatch

    CountDownLatch 是一个非常实用的多线程控制工具类." Count Down " 在英文中意为倒计数, Latch 为门问的意思.如果翻译成为倒计数门阀, 我想大家都会觉得不知所云吧! 因此,这里简单地称之为倒计数器.在这里, 门问的含义是:把门锁起来,不让里面的线程跑出来.因此,这个工具通常用来控制线程等待,它可以让某一个线程等待直到倒计时结束, 再开始执行. CountDown Latch 的构造函数接收一个整数作为参数,即当前这个计数器的计数个数. public Co

  • Java并发编程:CountDownLatch与CyclicBarrier和Semaphore的实例详解

    Java并发编程:CountDownLatch与CyclicBarrier和Semaphore的实例详解 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法. 以下是本文目录大纲: 一.CountDownLatch用法 二.CyclicBarrier用法 三.Semaphore用法 若有不正之处请多多谅解,并欢迎批评指正. 一.CountDownLatch

  • Java并发编程(CyclicBarrier)实例详解

    Java并发编程(CyclicBarrier)实例详解 前言: 使用JAVA编写并发程序的时候,我们需要仔细去思考一下并发流程的控制,如何让各个线程之间协作完成某项工作.有时候,我们启动N个线程去做一件事情,只有当这N个线程都达到某一个临界点的时候,我们才能继续下面的工作,就是说如果这N个线程中的某一个线程先到达预先定义好的临界点,它必须等待其他N-1线程也到达这个临界点,接下来的工作才能继续,只要这N个线程中有1个线程没有到达所谓的临界点,其他线程就算抢先到达了临界点,也只能等待,只有所有这N

  • Java并发编程Callable与Future的应用实例代码

    本文主要探究的是java并发编程callable与future的使用,分享了相关实例代码,具体介绍如下. 我们都知道实现多线程有2种方式,一种是继承Thread,一种是实现Runnable,但这2种方式都有一个缺陷,在任务完成后无法获取返回结果.要想获得返回结果,就得使用Callable,Callable任务可以有返回值,但是没法直接从Callable任务里获取返回值:想要获取Callabel任务的返回值,需要用到Future.所以Callable任务和Future模式,通常结合起来使用. 试想

  • java并发编程实例分析

    java并发编程是java程序设计语言的一块重点,在大部分的业务场景中都需要并发编程. 比如:并发的去处理http请求,这样就可以使得一台机器同时处理多个请求,大大提高业务的响应效率,从而使用用户体验更加流畅. java如何并发编程,要注意以下几个方面: 1.java语言中的多线程操作:创建和启动线程的几种方式. 2.共享变量的同步问题,要保证线程安全,辨别哪些变量是线程安全的.那些变量是线程不安全的,对于不安全的变量我们要想办法让其同步,一般也就是加锁. 3.线程锁:包括方法锁和synchro

随机推荐