java中的线程不安全和实例解析
一:引言(特指单核)
所谓线程不安全,就是在共享数据时,不同的线程在执行时,出现数据的不准确,(以模拟抢票和模拟银行取钱为例),那么我们的线程不安全具体指的是什么呢?是指我们的一个线程还未来结束,就被cpu时间切片切换到其他线程了,最终会导致我们的数据不准确
二:实例分析
1.抢票
package com.wyj.three;
/**
*
* 线程不安全:出现负数,和相等的票数
*
* @author 86155
*
*/
public class Demo1_线程不安全示例一 {public static void main(String[] args) {// TODO Auto-generated method stub//同一个资源son3 p = new son3();System.out.println(Thread.currentThread().getName());//获取当前线程的名字//多个代理new Thread(p,"王小杰").start();new Thread(p,"王中杰").start();new Thread(p,"王大杰").start();}}class son3 implements Runnable{private int ticketnums = 10;@Overridepublic void run() {// TODO Auto-generated method stubwhile(true) {if(this.ticketnums < 0)break;try {Thread.sleep(1000);//模拟网络延迟 } catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.err.println(Thread.currentThread().getName()+"--->"+ticketnums--);}}}
分析:
这里的出现负数和相同的数就是我们的线程不安全,出现负数,那是因为3个人在抢最后一张票时,都在通过sleep(),进入阻塞状态,也就是线程被中断了,cpu时间切片,切换到其他线程执行了,那么等待阻塞状态结束,就如就绪状态,待cpu调度是,继续执行sleep()下面的代码,这是就会出现问题,第一个人阻塞状态结束后,可能会抢到票,那么接下来的人,阻塞状态结束后,继续执行sleep()下面的代码,因为是共享资源,唯一一张票已经被抢走了,剩下0,再来一个那就-1;
对于出现相等的票,那是1个人待阻塞结束后,从主存中拷贝原来的进度数据,但这时cpu时间切片还未切换到他,这是又有一个人从主存当中拷贝了数据,数据没变化,那当cpu调度到的时候就会出现相同的票**
2:实例二银行取钱
package com.wyj.three;
/*** 所谓线程不安全 就是发生在 共享资源上 * 银行取钱 两个线程在执行完 取钱的之后cpu时间片就切换了 就是一个线程还未执行完 就切换到另一个了,这样的话* 账户连续两次的取钱80,也就是剩下的钱为-60 当cpu时间切片切换回来时,余额就为-60;* * * @author 86155**/
public class Demo2_线程不安全示例二 {public static void main(String[] args) {//开个账户Account a = new Account(100, "结婚礼金");Drawing t1 = new Drawing(a,80, "me");Drawing t2 = new Drawing(a, 80, "wife");t1.start();t2.start();}
}//账户
class Account{int money;String name;public Account(int money, String name) {super();this.money = money;this.name = name;}
}//取款
class Drawing extends Thread{Account account;//取钱的账户;int getmoney;//取得钱int summoney;//取得总数public Drawing(Account account, int getmoney,String name) {super(name);this.account = account;this.getmoney = getmoney;}public void run() {// if((account.money-=getmoney) < 0)
// return ;
//
// try {// Thread.sleep(1000);
// } catch (InterruptedException e) {// // TODO Auto-generated catch block
// e.printStackTrace();
// }account.money-=getmoney;summoney+=getmoney;System.out.println(this.getName()+"-->账户余额:"+account.money);System.out.println(this.getName()+"-->到手的钱:"+summoney);}}
分析:
银行取钱 两个线程在执行完 取钱的之后cpu时间片就切换了 就是一个线程还未执行完 就切换到另一个了,这样的话
账户连续两次的取钱80,也就是剩下的钱为-60 当cpu时间切片切换回来时,余额就为-60;
三:总结
归根到底这些问题都是线程不同步导致的, 就是一个线程还未结束,就开始另外一个线程,在共享资源的背景下肯定会出现数据错误
如有疑问请留言呀
java中的线程不安全和实例解析相关推荐
- java线程和内核线程的,Java中内核线程理论及实例详解
1.概念 内核线程是直接由操作系统内核控制的,内核通过调度器来完成内核线程的调度并负责将其映射到处理器上执行.内核态下的线程执行速度理论上是最高的,但是用户不会直接操作内核线程,而是通过内核线程的接口 ...
- 如何在java中实现线程_用代码说话:如何在Java中实现线程
并发编程是Java语言的重要特性之一,"如何在Java中实现线程"是学习并发编程的入门知识,也是Java工程师面试必备的基础知识.本文从线程说起,然后用代码说明如何在Java中实现 ...
- Java多线程编程(1)--Java中的线程
一.程序.进程和线程 程序是一组指令的有序集合,也可以将其通俗地理解为若干行代码.它本身没有任何运行的含义,它只是一个静态的实体,它可能只是一个单纯的文本文件,也有可能是经过编译之后生成的可执行文 ...
- JAVA中创建线程的三种方法及比较
JAVA中创建线程的方式有三种,各有优缺点,具体如下: 目录 一.继承Thread类来创建线程 二.实现Runnable接口来创建线程 三.通过Callable和Future来创建线程 四.三种方式创 ...
- Java中创建线程的三种方式
Java中创建线程主要有三种方式: 一.继承Thread类创建线程类 (1)继承Thread类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务.因此把run()方法称为执行体. ...
- 青铜2:本来面目-如何认识Java中的线程
在前面的<兵分三路:如何创建多线程>文章中,我们已经通过Thread和Runnable直观地了解如何在Java中创建一个线程,相信你已经有了一定的体感.在本篇文章中,我们将基于前面的示例代 ...
- Java中的线程基础篇-线程基本概念
线程的概念.创建方式.生命周期.优缺点 一.基础知识 1. 进程.线程.协程 1.1 进程 1.2 线程 1.3 协程 2. 串行.并发.并行 2.1 串行 2.2 并发 2.3 并行 二.线程的创建 ...
- Java中的线程基础知识
Java中的线程基础知识 1.线程概念 线程是程序运行的基本执行单元.当操作系统(不包括单线程的操作系统,如微软早期的DOS)在执行一个程序时,会在系统中建立一个进程,而在这个进程中,必须至少建立一个 ...
- java中的线程安全是什么?
java中的线程安全是什么: 就是线程同步的意思,就是当一个程序对一个线程安全的方法或者语句进行访问的时候,其他的不能再对他进行操作了,必须等到这次访问结束以后才能对这个线程安全的方法进行访问. 什么 ...
最新文章
- 《DNS与BIND(第5版)》——7.6 保持一切平稳运行
- pyBoard 基于MicroPython开发STM32FXX单片机
- 一条正确的Java职业生涯规划,从理论到实践!
- win2000输入密码后循环登陆,不能进入用户桌面
- Ubuntu1404 开启定时任务 crontab
- Windows下Yarn安装与使用
- Android第四十五天
- cisco ***笔记
- linux备份mysql数据库
- eclipse使用教程超详细讲解
- skyline在海洋及管线类3DGIS应用综述
- 单片机电子密码锁C语言程序,以STC89C52单片机为核心的电子密码锁设计
- AcWing 671. DDD
- 米豆网首页快照不更新原因分析
- 寒衣节的由来和习俗,你知道吗?
- 3S处理技术 -MapGIS转换shp攻略
- 铨顺宏RFID:电子汽车车牌系统具有RFID识别功能
- 【C标准库】详解feof函数与EOF
- ServU 5.0的配置
- 华为交换机查看网口光功率命令
热门文章
- 使用VS2015进行C++开发的6个主要原因
- 从业十余年谈谈对dotnet看法与坚持
- 【遥感数字图像处理】实验:Erdas 软件的认识与使用
- 【ArcGIS风暴】捕捉VS经典捕捉,谁更有用武之地?
- linux之hexdump命令
- C和指针之函数之递归实现厄密多项式
- linux c的连接库和怎么同时编译多个源程序
- Android之网络编程之网络通信几种方式实例分享
- [小白进] 大佬们学习为什么简单?小白该如何学习?学历不高如何找工作?副业很好赚?了解后少走弯路
- [TP5填坑]关于助手函数input一不小心取不到get值的解决办法