多线程中一定会遇到线程安全的问题,也就是在同一时间N条线程操作了同一变量,这个变量也叫做共享变量。

举例:(错误的示范)

  设计一个投票系统,多个人可以对同一个的票数进行投票,下面看具体代码:

代码:

/**
* 投票Demo 错误示范
*/
public class Test01 extends Thread { //小明的起始票数为0
int count = 0; @Override
public void run() {
super.run();
count++;
System.out.println(this.currentThread().getName() + "投完票之后,小明的票数增加到了:" + count);
} public static void main(String[] args) {
Test01 test01 = new Test01(); Thread a = new Thread(test01, "小红");
Thread b = new Thread(test01, "小亮");
Thread c = new Thread(test01, "小白");
Thread d = new Thread(test01, "小黑");
a.start();
b.start();
c.start();
d.start(); } }

看代码貌似没什么问题,但是见到打印的语句就会发现问题了:

小红投完票之后,小明的票数增加到了:2
小亮投完票之后,小明的票数增加到了:2
小白投完票之后,小明的票数增加到了:3
小黑投完票之后,小明的票数增加到了:4

明明小红投完票之后,小明的票应该是1,但是却变为了2,这就出现了多线程数据安全的问题,很容易发生共享数据错乱,要想解决这个办法,就应该使用synchronized来解决了。

注意看下面代码的变化:

/**
* 投票Demo 错误示范
*/
public class Test01 extends Thread { //小明的起始票数为0
int count = 0; //使用synchronized修饰之后就不会出现共享数据安全问题了
@Override
synchronized public void run() {
super.run();
count++;
System.out.println(this.currentThread().getName() + "投完票之后,小明的票数增加到了:" + count);
} public static void main(String[] args) {
Test01 test01 = new Test01(); Thread a = new Thread(test01, "小红");
Thread b = new Thread(test01, "小亮");
Thread c = new Thread(test01, "小白");
Thread d = new Thread(test01, "小黑");
a.start();
b.start();
c.start();
d.start(); } }

synchronized可以在任意方法和对象上面上锁,加锁这段代码称为“临界点”或者“互斥区”

到这里就可以解决多线程数据安全的问题了,这种问题在工作中是很常见的,一定要注意。

												

java多线程安全的问题的更多相关文章

  1. 40个Java多线程问题总结

    前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行 ...

  2. Java多线程基础知识篇

    这篇是Java多线程基本用法的一个总结. 本篇文章会从一下几个方面来说明Java多线程的基本用法: 如何使用多线程 如何得到多线程的一些信息 如何停止线程 如何暂停线程 线程的一些其他用法 所有的代码 ...

  3. Java多线程系列--“JUC锁”03之 公平锁(一)

    概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...

  4. Java多线程系列--“JUC锁”04之 公平锁(二)

    概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...

  5. Java多线程--让主线程等待子线程执行完毕

    使用Java多线程编程时经常遇到主线程需要等待子线程执行完成以后才能继续执行,那么接下来介绍一种简单的方式使主线程等待. java.util.concurrent.CountDownLatch 使用c ...

  6. Java多线程 2 线程的生命周期和状态控制

    一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就 ...

  7. java 多线程 1 线程 进程

    Java多线程(一).多线程的基本概念和使用 2012-09-10 16:06 5108人阅读 评论(0) 收藏 举报  分类: javaSE综合知识点(14)  版权声明:本文为博主原创文章,未经博 ...

  8. 一起阅读《Java多线程编程核心技术》

    目录 第一章 Java多线程技能 (待续...)

  9. 第一章 Java多线程技能

    1.初步了解"进程"."线程"."多线程" 说到多线程,大多都会联系到"进程"和"线程".那么这两者 ...

  10. java从基础知识(十)java多线程(下)

    首先介绍可见性.原子性.有序性.重排序这几个概念 原子性:即一个操作或多个操作要么全部执行并且执行的过程不会被任何因素打断,要么都不执行. 可见性:一个线程对共享变量值的修改,能够及时地被其它线程看到 ...

随机推荐

  1. defer=“defer”和async=“async”

    <script type="text/javascript" src="demo_defer.js" defer="defer"> ...

  2. Vue.js(2.x)之插值

    看了一些友邻写的文章,不少是基于1.0版本的,有些东西在2.x版本应该已经废除了(如属性插值.单次插值在2.x版本上运行根本不执行).对于不理解的东东,找起资料来就更麻烦了.不得不老老实实线下测试并整 ...

  3. Windows 10 取消桌面右键“图像属性”、“图像选项”

    Windows 10 取消桌面右键"图像属性"."图像选项" 桌面右键 说明:在windows 10中,桌面右键出现"图像属性"." ...

  4. 不该被忽视的CoreJava细节(四)

    令人纳闷的数组初始化细节 这个细节问题我很久以前就想深入研究一下,但是一直没有能够抽出时间,借这系列文章的东风,尽量解决掉这个"心头病". 下面以一维int数组为例,对数组初始化方 ...

  5. [VC]VC实现开机自动运行程序

    有时候,我们需要在计算机启动的时候就启动某些程序,不要人干预.这里,提供一种让程序开机自动运行的方法.见下面代码: BOOL CXXX::SetAutoRun(CString strPath) { C ...

  6. Objective-C try/catch异常处理机制原理。

    try-catch-finaly finally在任何情况下都会执行(不管有没有异常),属于整个体系的附属. 基本思想是跳到捕获锚点,重新执行. http://www.cnblogs.com/mark ...

  7. Objective-C 引用计数原理

    http://www.cocoachina.com/ios/20160112/14933.html 引用计数如何存储 有些对象如果支持使用 TaggedPointer,苹果会直接将其指针值作为引用计数 ...

  8. 【BZOJ1101】[POI2007] Zap(莫比乌斯反演)

    点此看题面 大致题意: 求\(\sum_{x=1}^N\sum_{y=1}^M[gcd(x,y)==d]\). 一道类似的题目 推荐先去做一下这道题:[洛谷2257]YY的GCD,来初步了解一下莫比乌 ...

  9. 安装CentOS6.9虚拟机

    安装CentOS6.9 之前在学习项目时,都是用的按键好的虚拟机.这次自己也尝试搭建一下.(虽然也是google的) 首先大部分过程都是参考https://blog.csdn.net/pengpeng ...

  10. Java十进制转成二进制 八进制 十六进制

    int a = 357;//十进制转成二进制System.out.println(Integer.toBinaryString(a)); package com.swift; import java. ...