[Java]Java多线程数据安全(同步线程的方法)
来源:互联网 发布:数据集中器 编辑:程序博客网 时间:2024/04/29 10:19
原创文章,欢迎转载。转载请注明:转载自 祥的博客
原文链接:http://blog.csdn.net/humanking7/article/details/43541387
预备知识
Thread.yield():
API中解释: 暂停当前正在执行的线程对象,并执行其他线程。
注意:这里的其他也包含当前线程,即,当前线程也能够再次抢占CPU。
Thread.sleep(long millis):
API解释:使当前线程暂停millis所指定的毫秒,转到执行其它线程。
不使用关键字synchronized(容易出错)
Java源代码
public class MyRunnable implements Runnable{ private int num = 100; @Override public void run() { while(true){ System.out.println(Thread.currentThread().getName() + "@: " + this.num); this.num --; Thread.yield(); //为了更容易产生错误 if(this.num < 0){ break; } } } public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); Thread th1 = new Thread(myRunnable,"线程A"); Thread th2 = new Thread(myRunnable,"线程B"); th1.start(); th2.start(); }}
运行结果
上述错误就是典型的多线程访问数据错误。
分析
我来试着分析一下产生这个错误的原因:
- 刚开始线程B执行,但是在马上要打印到屏幕的时候(执行到这个代码中
System.out.println(Thread.currentThread().getName() + "@: " + this.num);
),被线程A抢到CPU了; - 此时
num
还没没有执行自减操作,即num == 100
; - 这个时候CPU一直被线程A占用着,一直运行,到打印出
线程A@:94
时,线程A抢到了CPU; - 线程B打印出
线程B@:100
,其实此时num == 93
,只是原来把100
数据已经写进了程序的堆栈中; - 接着线程B继续执行代码,
num
自减,即num == 92
; - 下面就是线程B愉快的执行代码了。
使用synchronized同步代码块
Java源代码
public class MyRunnable implements Runnable{ private int num = 100; @Override public void run() { while(true){ System.out.println(Thread.currentThread().getName()); synchronized(this){ System.out.println(Thread.currentThread().getName() + "@: " + this.num); this.num --; Thread.yield();//为了更容易产生错误 if(this.num < 0){ break; } } } } public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); Thread th1 = new Thread(myRunnable,"线程A"); Thread th2 = new Thread(myRunnable,"线程B"); th1.start(); th2.start(); }}
运行结果
分析
我来分析一下用红框标记结果的执行流程。
分析之前先设定代码System.out.println(Thread.currentThread().getName());
为代码1,设定代码System.out.println(Thread.currentThread().getName() + "@: " + this.num);
为代码2。
- 线程B获取CPU,执行了代码1;
- 线程B进入同步代码块,执行了代码2,但还没有退出同步代码块的时候,线程A抢到了CPU;
- 线程A执行了代码1,但是无法进入同步代码块,只能等待,这时候线程B获得了CPU,继续执行代码,执行到了代码1时,线程A又获得了CPU;
- 线程A接着刚才继续执行,此时因为线程B已经不在同步代码块中,所以线程A就可以进入同步代码块,执行代码2。
真是绕啊,分析完毕,不知道有没有什么错误,还望大家批评指正,共同进步。
0 0
- [Java]Java多线程数据安全(同步线程的方法)
- JAVA 多线程--线程同步安全
- Java多线程-线程的同步(同步方法)
- Java多线程-线程的同步(同步方法)
- Java多线程-线程的同步(同步方法)
- java-多线程 | 线程安全和线程同步
- java多线程(二)之线程安全和线程同步
- java多线程3-线程的同步与数据传递
- java多线程:线程的同步-同步块
- 多线程同步(线程安全,同步方法)
- Java线程:线程的同步-同步方法
- Java线程:线程的同步-同步方法
- Java线程:线程的同步-同步方法
- Java线程:线程的同步-同步方法
- Java线程:线程的同步-同步方法
- Java线程:线程的同步-同步方法
- Java线程:线程的同步-同步方法
- Java线程:线程的同步-同步方法
- Mac下Sublime Text 3安装PackageControl以及一些常用插件
- node.js搭建一个简单的电影网站
- 少女遭父母铁链捆腿毒打 戴脚镣翻墙逃进深山
- 使用PHP调用TinyURL API的方法
- 系统安全——软件健壮性
- [Java]Java多线程数据安全(同步线程的方法)
- VirtualTreeview鼠标移动到相应节点时,节点背景颜色发生变化
- 基于REST架构的Web Service设计
- 丈夫三次“买凶杀妻” 妻子毫无所觉称婚姻甜蜜
- JavaScript通过Flash保存本地数据
- Metasploit生成Stage shellcode
- Android - popupwindow
- DB2ASP数据库ASP页面生成工具
- UILabel上显示过长NSString文本的方式