android多线程安全问题,Android-多线程安全问题-synchronized

先看一个售票案例Demo,多线程程序对共享数据操作引发的安全问题:

package android.java.thread09;

/**

* 售票线程

*/

class Booking implements Runnable {

/**

* 模拟票的总算 10张票

*/

private int ticket = 10;

@Override

public void run() {

while (true) {

if (ticket > 0) {

// 让线程在这里停一下,会更加容易复现线程的安全问题,就算不加这行代码,安全问题依然有

try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }

System.out.println("名称:" + Thread.currentThread().getName() + "窗口卖出第" + ticket + "张票");

ticket--;

}

}

}

}

/**

* 售票案例

*/

public class BookingTest {

public static void main(String[] args) {

/**

* 定义Runnable实现类Booking,此实现类Booking不是线程,此实现类Booking给四个Thread去执行的

*/

Runnable booking = new Booking();

// 实例化线程对象

Thread thread1 = new Thread(booking); // 此实现类Booking给Thread去执行的

Thread thread2 = new Thread(booking); // 此实现类Booking给Thread去执行的

Thread thread3 = new Thread(booking); // 此实现类Booking给Thread去执行的

Thread thread4 = new Thread(booking); // 此实现类Booking给Thread去执行的

// 开启启动线程

thread1.start(); // 启动第Thread-0窗口 执行卖票任务

thread2.start(); // 启动第Thread-1窗口 执行卖票任务

thread3.start(); // 启动第Thread-2窗口 执行卖票任务

thread4.start(); // 启动第Thread-3窗口 执行卖票任务

}

}

打印的日志结果,注意:⚠️ 没有打印的日志结果都不同,这是CPU对线程非常快速的切换造成的,哪个线程先有执行权 就执行哪个线程 都是随机的

名称:Thread-0窗口卖出第10张票

名称:Thread-3窗口卖出第9张票

名称:Thread-1窗口卖出第8张票

名称:Thread-2窗口卖出第7张票

名称:Thread-0窗口卖出第6张票

名称:Thread-3窗口卖出第5张票

名称:Thread-2窗口卖出第4张票

名称:Thread-1窗口卖出第4张票

名称:Thread-2窗口卖出第2张票

名称:Thread-0窗口卖出第1张票

名称:Thread-3窗口卖出第1张票

名称:Thread-1窗口卖出第-1张票

名称:Thread-2窗口卖出第-2张票

CPU的随机性,到底切换到哪个线程,到底执行哪个线程代码的多少行,等等,都是随机的

android多线程安全问题,Android-多线程安全问题-synchronized_第1张图片

分析原因,为什么会出现以上日志打印的各个情况呢,为什么会出现 0张票 -1张票   这种情况呢?,看以下CPU执行线程的随机性就明白了

android多线程安全问题,Android-多线程安全问题-synchronized_第2张图片

通过以上画图分析原因,造成安全问题的有以下两个因素:

1.线程任务中,发现有共享数据,例如:ticket。

2.多线程操作共享数据,例如:ticket。

造成的原因是:Thread-0在对共享数据操作过程中,CPU执行了Thread-1对共享数据操作,   相当于:我在数钱,突然我出去有事了,然后有个人拿了500块钱,等我在回来数钱的时候,就已经发生是数据安全问题

解决多线程安全问题,synchronize 加同步代码块,同步代码块:synchronize{ 操作共享数据的代码 }

android多线程安全问题,Android-多线程安全问题-synchronized_第3张图片

package android.java.thread09;

/**

* 售票线程

*/

class Booking implements Runnable {

/**

* 模拟票的总算 10张票

*/

private int ticket = 10;

@Override

public void run() {

while (true) {

/**

* 加入了同步代码块的代码synchronized,

* 不管CPU如何疯狂的切换执行,

* 只要同步代码块里面的代码没有执行完,

* 就不准其他线程进来执行

* 这样就保证了多线程操作共享数据的安全新

*/

synchronized (Booking.class) { // 同步操作共享数据的代码

if (ticket > 0) {

// 让线程在这里停一下,会更加容易复现线程的安全问题,就算不加这行代码,安全问题依然有

try {

Thread.sleep(200);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("名称:" + Thread.currentThread().getName() + "窗口卖出第" + ticket + "张票");

ticket--;

}

}

}

}

}

/**

* 售票案例

*/

public class BookingTest {

public static void main(String[] args) {

/**

* 定义Runnable实现类Booking,此实现类Booking不是线程,此实现类Booking给四个Thread去执行的

*/

Runnable booking = new Booking();

// 实例化线程对象

Thread thread1 = new Thread(booking); // 此实现类Booking给Thread去执行的

Thread thread2 = new Thread(booking); // 此实现类Booking给Thread去执行的

Thread thread3 = new Thread(booking); // 此实现类Booking给Thread去执行的

Thread thread4 = new Thread(booking); // 此实现类Booking给Thread去执行的

// 开启启动线程

thread1.start(); // 启动第Thread-0窗口 执行卖票任务

thread2.start(); // 启动第Thread-1窗口 执行卖票任务

thread3.start(); // 启动第Thread-2窗口 执行卖票任务

thread4.start(); // 启动第Thread-3窗口 执行卖票任务

}

}

以下日志结果,是CPU随机执行到哪个线程,就哪个线程打印,CPU执行线程的随机性很重要

android多线程安全问题,Android-多线程安全问题-synchronized_第4张图片

以下日志结果,是CPU随机执行到哪个线程,就哪个线程打印,CPU执行线程的随机性很重要

android多线程安全问题,Android-多线程安全问题-synchronized_第5张图片

以下日志结果,是CPU随机执行到哪个线程,就哪个线程打印,CPU执行线程的随机性很重要

android多线程安全问题,Android-多线程安全问题-synchronized_第6张图片

.........

java多线程以及Android多线程

Java 多线程 线程和进程的区别 线程和进程的本质:由CPU进行调度的并发式执行任务,多个任务被快速轮换执行,使得宏观上具有多个线程或者进程同时执行的效果. 进程:在操作系统来说,一个运行的程序或者 ...

Android多线程分析之四:MessageQueue的实现

Android多线程分析之四:MessageQueue的实现 罗朝辉 (http://www.cnblogs.com/kesalin/) CC 许可,转载请注明出处 在前面两篇文章

Android多线程分析之三:Handler,Looper的实现

Android多线程分析之三:Handler,Looper的实现 罗朝辉 (http://www.cnblogs.com/kesalin/) CC 许可,转载请注明出处 在前文

Android多线程分析之二:Thread的实现

Android多线程分析之二:Thread的实现 罗朝辉 (http://www.cnblogs.com/kesalin/) CC 许可,转载请注明出处   在前文

java基础知识回顾之java Thread类学习(四)--java多线程安全问题(锁)

上一节售票系统中我们发现,打印出了错票,0,-1,出现了多线程安全问题.我们分析为什么会发生多线程安全问题? 看下面线程的主要代码: @Override public void run() { // ...

android 多线程断点续传下载

今天跟大家一起分享下Android开发中比较难的一个环节,可能很多人看到这个标题就会感觉头很大,的确如果没有良好的编码能力和逻辑思维,这块是很难搞明白的,前面2次总结中已经为大家分享过有关技术的一些基 ...

Android多线程及异步处理问题

1.问题提出 1)为何需要多线程? 2)多线程如何实现? 3)多线程机制的核心是啥? 4)到底有多少种实现方式? 2.问题分析 1)究其为啥需要多线程的本质就是异步处理,直观一点说就是不要让用户感觉到 ...

多线程安全问题之Lock显示锁

package com.hls.juc; import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.Reentr ...

随机推荐

不同材质怎么通过ZBrush赋予同一个模型上

ZBrush 作为最专业的数字雕刻与绘画软件,能够制作出高质量的3D模型,包括模型的颜色贴图和材质属性.不同材质可以改变照明在表面上的反应,以便模型表现出光泽.凹凸.反射.金属性或透明效果.ZBrus ...

搭建dns域名服务器过程

在用TCP/IP协议族架设的网络中,每一个节点都有一个唯一的IP地址,用来作为它们唯一的标志.然而,如果让使用者来记住这些毫无记忆规律的IP地址将是不可想象的.人们就需要一种有记忆规律的字符串来作为唯 ...

[转] Putty - 文件夹显示的蓝色太暗

Putty SSH key的后缀为ppk 默认文件夹的颜色显示为ANSI Blue,颜色太暗. ANSI Blue : RGB(0, 0, 187) 将ANSI Blue修改为和ANSI Blue B ...

Socket编程实践(13) --UNIX域协议

UNIX域协议 UNIX域套接字与TCP相比, 在同一台主机上, UNIX域套接字更有效率, 几乎是TCP的两倍(由于UNIX域套接字不需要经过网络协议栈,不需要打包/拆包,计算校验和,维护序号和应答 ...

SpringBoot aop 注解 数据权限校验

注解类: @Retention(RetentionPolicy.RUNTIME) public @interface DataAuthValid { //位置 public int index() d ...

js 日期格式转换(转载)

1.当前时间转为 “yyyy-MM-dd HH:MM:SS” function getNowFormatDate() { var date = new Date(); var seperator1 = ...

percona-server-5.7.18-14安装

说明 percona-server-5.7 的安装对硬件配置的要求较高,至少需要4G内存或者2G物理内存+2Gswap. 编译安装过程中注意所在分区的空间大小,编译安装需要使用到大量的临时空间. 环境 ...

fzu 2082 过路费 (树链剖分+线段树 边权)

Problem 2082 过路费 Accept: 887    Submit: 2881Time Limit: 1000 mSec    Memory Limit : 32768 KB  Proble ...

vue 和 react 选择

经典 react 还是有其优点的, 生态更丰富,  更容易 测试 和 调试, 更适合超大型应用,  更适合app,  weex不一定能到达 reactNative的高度 而vue , 更为直观, 上手 ...

Spring JdbcTemplate查询实例

这里有几个例子向您展示如何使用JdbcTemplate的query()方法来查询或从数据库提取数据.整个项目的目录结构如下: 1.查询单行数据 这里有两种方法来查询或从数据库中提取单行记录,并将其转换 ...

你可能感兴趣的:(android多线程安全问题)