线程安全问题产生原因:
1、多个线程操作共享的数据;
2、操作共享数据的线程代码有多条。
 
当一个线程正在执行操作共享数据的多条代码过程中,其它线程也参与了运算,
就会导致线程安全问题的发生。
class Ticket extends Thread
{
private int num = 100;
public void run()
{
while(num > 0)
{
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "..." + num-- );
}
}
} public class MyDemo { public static void main(String[] args) {
// TODO Auto-generated method stub Runnable ticket = new Ticket(); Thread t1 = new Thread(ticket);
Thread t2 = new Thread(ticket);
Thread t3 = new Thread(ticket);
Thread t4 = new Thread(ticket); t1.start();
t2.start();
t3.start();
t4.start();
}
}
Output:
Thread-1...11
Thread-2...10
Thread-4...9
Thread-3...8
Thread-2...7
Thread-1...6
Thread-3...5
Thread-4...4
Thread-1...2
Thread-2...3
Thread-4...1
Thread-3...0
Thread-2...-1
Thread-1...-2
 

解决思路:

就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,
其他线程时不可以参与运算的。
必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。 
 
在java中,用同步代码块就可以解决这个问题。
 
同步代码块的格式:
synchronized(对象)
{
需要被同步的代码 ;
}
同步的好处:解决了线程的安全问题。
同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁
同步的前提:同步中必须有多个线程并使用同一个锁。
Example:
class Ticket implements Runnable
{
private int num = 100;
Object obj = new Object(); public void run()
{
// 如果将同步锁对象obj定义在此处,则会在每一个线程中都创建一个同步锁,
//即无法实现线程的同步。
while(true)
{
synchronized(obj) //同步代码块
{
if(num > 0)
{
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "..." + num--);
}
}
} } } public class MyDemo { public static void main(String[] args) {
// TODO Auto-generated method stub Runnable ticket = new Ticket(); Thread t1 = new Thread(ticket);
Thread t2 = new Thread(ticket);
Thread t3 = new Thread(ticket);
Thread t4 = new Thread(ticket);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
Output:
Thread-2...17
Thread-2...16
Thread-2...15
Thread-2...14
Thread-2...13
Thread-2...12
Thread-3...11
Thread-3...10
Thread-3...9
Thread-3...8
Thread-3...7
Thread-3...6
Thread-3...5
Thread-3...4
Thread-3...3
Thread-3...2
Thread-3...1
 
Example:
class Ticket extends Thread
{
private int num = 100;
Object obj = new Object(); public void run()
{ while(true)
{
synchronized(obj)
{
if(num > 0)
{
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "..." + num--);
}
}
} } } public class MyDemo { public static void main(String[] args) {
// TODO Auto-generated method stub Ticket t1 = new Ticket();
Ticket t2 = new Ticket();
Ticket t3 = new Ticket();
Ticket t4 = new Ticket();
t1.start();
t2.start();
t3.start();
t4.start();
}
}
Output:
Thread-3...2
Thread-1...7
Thread-2...10
Thread-0...4
Thread-3...1
Thread-2...9
Thread-1...6
Thread-0...3
Thread-1...5
Thread-0...2
Thread-2...8
Thread-2...7
Thread-0...1
Thread-1...4
Thread-1...3
Thread-2...6
Thread-2...5
Thread-1...2
Thread-2...4
Thread-1...1
Thread-2...3
Thread-2...2
Thread-2...1
/*
同步函数的使用的锁是this;
同步函数和同步代码块的区别:
同步函数的锁是固定的this。
同步代码块的锁是任意的对象。
建议使用同步代码块。
*/
class Ticket implements Runnable
{
private int num = 100;
boolean flag = true;
public void run()
{
if(flag)
while(true)
{
synchronized(this)
{
if(num>0)
{
try{Thread.sleep(10);}catch (InterruptedException e){}
System.out.println(Thread.currentThread().getName()+".....obj...."+num--);
}
}
}
else
while(true)
this.show();
} public synchronized void show()
{
if(num>0)
{
try{Thread.sleep(10);}catch (InterruptedException e){} System.out.println(Thread.currentThread().getName()+".....function...."+num--);
}
}
} class SynFunctionLockDemo
{
public static void main(String[] args)
{
Ticket t = new Ticket(); Thread t1 = new Thread(t);
Thread t2 = new Thread(t); t1.start();
try{Thread.sleep(10);}catch(InterruptedException e){}
t.flag = false;
t2.start();
}
}
Output:
Thread-0.....obj....100
Thread-0.....obj....99
Thread-0.....obj....98
Thread-1.....function....97
Thread-1.....function....96
Thread-1.....function....95
Thread-1.....function....94
Thread-1.....function....93
Thread-1.....function....92
Thread-1.....function....91
Thread-1.....function....90
Thread-1.....function....89
Thread-1.....function....88
Thread-1.....function....87
Thread-1.....function....86
Thread-1.....function....85
Thread-1.....function....84
Thread-1.....function....83
Thread-1.....function....82
Thread-1.....function....81
Thread-1.....function....80
Thread-1.....function....79
Thread-1.....function....78
Thread-1.....function....77
Thread-1.....function....76
Thread-1.....function....75
Thread-1.....function....74
Thread-1.....function....73
Thread-1.....function....72
Thread-1.....function....71
Thread-1.....function....70
Thread-1.....function....69
Thread-1.....function....68
Thread-1.....function....67
Thread-1.....function....66
Thread-1.....function....65
Thread-1.....function....64
Thread-1.....function....63
Thread-1.....function....62
Thread-1.....function....61
Thread-1.....function....60
Thread-1.....function....59
Thread-1.....function....58
Thread-1.....function....57
Thread-1.....function....56
Thread-1.....function....55
Thread-1.....function....54
Thread-1.....function....53
Thread-1.....function....52
Thread-1.....function....51
Thread-1.....function....50
Thread-1.....function....49
Thread-1.....function....48
Thread-1.....function....47
Thread-1.....function....46
Thread-1.....function....45
Thread-1.....function....44
Thread-1.....function....43
Thread-1.....function....42
Thread-1.....function....41
Thread-1.....function....40
Thread-1.....function....39
Thread-1.....function....38
Thread-1.....function....37
Thread-1.....function....36
Thread-1.....function....35
Thread-1.....function....34
Thread-1.....function....33
Thread-1.....function....32
Thread-1.....function....31
Thread-1.....function....30
Thread-1.....function....29
Thread-1.....function....28
Thread-1.....function....27
Thread-1.....function....26
Thread-1.....function....25
Thread-1.....function....24
Thread-1.....function....23
Thread-1.....function....22
Thread-1.....function....21
Thread-1.....function....20
Thread-1.....function....19
Thread-1.....function....18
Thread-1.....function....17
Thread-1.....function....16
Thread-1.....function....15
Thread-1.....function....14
Thread-1.....function....13
Thread-1.....function....12
Thread-1.....function....11
Thread-1.....function....10
Thread-1.....function....9
Thread-1.....function....8
Thread-1.....function....7
Thread-1.....function....6
Thread-1.....function....5
Thread-1.....function....4
Thread-1.....function....3
Thread-1.....function....2
Thread-1.....function....1
 
/*
静态的同步函数使用的锁是  该函数所属字节码文件对象 
可以用 getClass方法获取,也可以用当前  类名.class 表示。
*/
/* synchronized作用于静态方法和非静态方法的区别:
* 非静态方法:
* 给对象加锁(可以理解为给这个对象的内存上锁,注意 只是这块内存,其他同类对象都会有各自的内存锁),这时候
* 在其他一个以上线程中执行该对象的这个同步方法(注意:是该对象)就会产生互斥
* 静态方法:
* 相当于在类上加锁(*.class 位于代码区,静态方法位于静态区域,这个类产生的对象公用这个静态方法,所以这块
* 内存,N个对象来竞争), 这时候,只要是这个类产生的对象,在调用这个静态方法时都会产生互斥
*/
class Ticket implements Runnable
{
private static int num = 100;
boolean flag = true;
public void run()
{ if(flag)
while(true)
{
synchronized(this.getClass()) // Ticket.class
{
if(num>0)
{
try{Thread.sleep(10);}catch (InterruptedException e){}
System.out.println(Thread.currentThread().getName()+".....obj...."+num--);
}
}
}
else
while(true)
show();
} public static synchronized void show()
{
if(num>0)
{
try{Thread.sleep(10);}catch (InterruptedException e){} System.out.println(Thread.currentThread().getName()+".....function...."+num--);
}
}
} class SynFunctionLockDemo
{
public static void main(String[] args)
{
Ticket t = new Ticket(); Thread t1 = new Thread(t);
Thread t2 = new Thread(t); t1.start();
try{Thread.sleep(10);}catch(InterruptedException e){}
t.flag = false;
t2.start();
}
}
Output:
Thread-0.....obj....100
Thread-1.....function....99
Thread-1.....function....98
Thread-0.....obj....97
Thread-0.....obj....96
Thread-0.....obj....95
Thread-0.....obj....94
Thread-0.....obj....93
Thread-0.....obj....92
Thread-0.....obj....91
Thread-0.....obj....90
Thread-0.....obj....89
Thread-0.....obj....88
Thread-0.....obj....87
Thread-0.....obj....86
Thread-0.....obj....85
Thread-0.....obj....84
Thread-0.....obj....83
Thread-0.....obj....82
Thread-0.....obj....81
Thread-0.....obj....80
Thread-0.....obj....79
Thread-0.....obj....78
Thread-0.....obj....77
Thread-0.....obj....76
Thread-0.....obj....75
Thread-0.....obj....74
Thread-0.....obj....73
Thread-0.....obj....72
Thread-0.....obj....71
Thread-0.....obj....70
Thread-0.....obj....69
Thread-0.....obj....68
Thread-0.....obj....67
Thread-0.....obj....66
Thread-0.....obj....65
Thread-0.....obj....64
Thread-0.....obj....63
Thread-0.....obj....62
Thread-0.....obj....61
Thread-0.....obj....60
Thread-0.....obj....59
Thread-0.....obj....58
Thread-0.....obj....57
Thread-0.....obj....56
Thread-0.....obj....55
Thread-0.....obj....54
Thread-0.....obj....53
Thread-0.....obj....52
Thread-0.....obj....51
Thread-0.....obj....50
Thread-0.....obj....49
Thread-0.....obj....48
Thread-0.....obj....47
Thread-0.....obj....46
Thread-0.....obj....45
Thread-0.....obj....44
Thread-0.....obj....43
Thread-0.....obj....42
Thread-0.....obj....41
Thread-0.....obj....40
Thread-0.....obj....39
Thread-0.....obj....38
Thread-0.....obj....37
Thread-0.....obj....36
Thread-0.....obj....35
Thread-0.....obj....34
Thread-0.....obj....33
Thread-0.....obj....32
Thread-0.....obj....31
Thread-0.....obj....30
Thread-0.....obj....29
Thread-0.....obj....28
Thread-0.....obj....27
Thread-0.....obj....26
Thread-0.....obj....25
Thread-0.....obj....24
Thread-0.....obj....23
Thread-0.....obj....22
Thread-0.....obj....21
Thread-0.....obj....20
Thread-0.....obj....19
Thread-0.....obj....18
Thread-0.....obj....17
Thread-0.....obj....16
Thread-0.....obj....15
Thread-0.....obj....14
Thread-1.....function....13
Thread-1.....function....12
Thread-1.....function....11
Thread-1.....function....10
Thread-1.....function....9
Thread-1.....function....8
Thread-1.....function....7
Thread-1.....function....6
Thread-1.....function....5
Thread-1.....function....4
Thread-1.....function....3
Thread-1.....function....2
Thread-1.....function....1
 

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

  1. (转)java线程安全问题之静态变量、实例变量、局部变量

    java多线程编程中,存在很多线程安全问题,至于什么是线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同<java并发编程实践>中所说: 写道 给线程安全下定义比较困难.存在很多种定义,如 ...

  2. java线程安全问题以及使用synchronized解决线程安全问题的几种方式

    一.线程安全问题 1.产生原因 我们使用java多线程的时候,最让我们头疼的莫过于多线程引起的线程安全问题,那么线程安全问题到底是如何产生的呢?究其本质,是因为多条线程操作同一数据的过程中,破坏了数据 ...

  3. java线程安全问题之静态变量、实例变量、局部变量

    java多线程编程中,存在很多线程安全问题,至于什么是线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同<java并发编程实践>中所说: 写道 给线程安全下定义比较困难.存在很多种定义,如 ...

  4. java线程安全问题原因及解决办法

    1.为什么会出现线程安全问题 计算机系统资源分配的单位为进程,同一个进程中允许多个线程并发执行,并且多个线程会共享进程范围内的资源:例如内存地址.当多个线程并发访问同一个内存地址并且内存地址保存的值是 ...

  5. Java 线程安全问题的本质

    原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 目录: 线程安全问题的本质 理解CPU JVM虚拟机类比于操作系统 重排序 汇总 一些解释 ...

  6. Java线程安全问题

    线程安全问题是一个老生常谈的问题,那么多线程环境下究竟有那些问题呢?这么说吧,问题的形式多种多样的,归根结底的说是共享资源问题,无非可见性与有序性问题. 1. 可见性 可见性是对于内存中的共享资源来说 ...

  7. java线程安全问题原理性分析

    1.什么是线程安全问题? 从某个线程开始访问到访问结束的整个过程,如果有一个访问对象被其他线程修改,那么对于当前线程而言就发生了线程安全问题:如果在整个访问过程中,无一对象被其他线程修改,就是线程安全 ...

  8. 关于 SimpleDateFormat 的非线程安全问题及其解决方案

    一直以来都是直接用SimpleDateFormat开发的,没想着考虑线程安全的问题,特记录下来(摘抄的): 1.问题: 先来看一段可能引起错误的代码: package test.date; impor ...

  9. Java多线程--线程安全问题的相关研究

    在刚刚学线程的时候我们经常会碰到这么一个问题:模拟火车站售票窗口售票.代码如下: package cn.blogs.com.isole; /* 模拟火车站售票窗口售票,假设有50张余票 */ publ ...

随机推荐

  1. php实现姓名按首字母排序的类与方法

    php将名字按首字母进行排序 <?php public function getFirstChar($s){ $s0 = mb_substr($s,0,3); //获取名字的姓 $s = ico ...

  2. Python学习 :面向对象 -- 成员修饰符

    成员修饰符 两种成员 - 公有成员 - 私有成员, __字段名 - 无法直接访问,只能通过内部方法来间接访问私有成员 简例:公有成员与私有成员  class Info: country = '中国' ...

  3. 总结2018&&展望2019

    2019很激动,因为我加入了博客园这个大家庭,以后的技术文章都会在博客园记录,也希望可以结识更多的有趣朋友和共同理想的友人.第一篇文章从自我规划开始.2019 您好!!! 总结2018: 距离2018 ...

  4. mysql底层实现

    MySQL 的常用引擎 1. InnoDB InnoDB 的存储文件有两个,后缀名分别是 .frm 和 .idb,其中 .frm 是表的定义文件,而 idb 是数据文件. InnoDB 中存在表锁和行 ...

  5. Windows10下ghci无法使用的解决方案之一

    遇到的问题:在安装Haskell Platform Core 8.4.3版本后,在命令行中输入ghci,使用该交互环境时报错. 报错信息如下:省略号是一系列类似ghci去各种路径查找都没找到的信息 G ...

  6. 【8086汇编-Day1】预备知识

    菜鸟的8086汇编入门之旅,偶有错处恭请大佬们指正. Ⅰ· 闲说一下 我为什么学汇编?相对于晦涩难懂的01010101011010机器语言(高低电平变化驱动机器做出不同反应),汇编语言用更便于记忆和使 ...

  7. 20155216 2017-2018-1 《信息安全系统设计基础》第二周课堂练习补交以及Myod的实现

    20155216 2017-2018-1 <信息安全系统设计基础>第二周课堂练习补交 课堂测试3:行断点的设置 运行截图: 未完成原因:课前未安装 cgdb 具体步骤: 1.输入命令:gc ...

  8. C语言复习20170821

    函数 函数头部参数表里的变量称为形参,也是内部变量,只能在函数体内访问. 形参的作用是实现主调函数与被调函数之间的联系,通常将函数所处理的数据,影响函数功能的因素或者函数处理的结果作为形参.没有形参的 ...

  9. Yii2.0 技巧总结

    View部分 1. 使用ActiveField中的hint生成提示文字 <?= $form->field($model, 'freightAddedFee')->textInput( ...

  10. 提取oracle awr报告

    做性能测试时有时需要分析sql的执行情况,以找出需要优化的sql,oracle数据库就提供了很好的数据库状态和sql执行情况的监控平台,数据库的监控平台可以时时的监控数据库的状态,同时还可以取监控的时 ...