Java线程安全问题及线程安全解决方法
2015-11-26 22:32
579 查看
Java线程安全问题一直是一个热议的话题,笔者在开发或面试过程中常遇到类似这样的问题 下面我来总结一下:
线程安全的原因 :线程安全是由于多个线程在数据共享过程中出现了异常,比如一个线程还未执行完成,另一个线程就参与了进来,导致共享的数据不准确。那么我们如何来解决线程安全问题呢?方法有多种 笔者就先列举一种方法叫"安全代码块"关键代码synchronized 具体例子如下:
方式一: 安全代码块,用关键代码synchronized包围代码块,该方法的锁为this
1.class SaleTicket implements Runnable{
static int ticket=100;//静态变量
public void run(){
while(true){
synchronized(this){//this指SaleTicket
if(ticket>0){
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"售出票号为"+ ticket--);
}
}
}
public static void main(String[] args) {
SaleTicket saler1=new SaleTicket();
Thread t1=new Thread(saler1);
Thread t2=new Thread(saler1);
Thread t3=new Thread(saler1);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
方式二:安全方法 用synchronized声明方法 该方法的锁为this即为当前对象
public void run() {
show();
}
public synchronized void show(){
while(true){
if(ticket>0){
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"售出票号为"+ ticket--);
}
}
2.输出结果一样为:
窗口2售出票号为100
窗口3售出票号为99
窗口3售出票号为98
窗口3售出票号为97
窗口3售出票号为96
窗口3售出票号为95
窗口3售出票号为94
窗口3售出票号为93
窗口3售出票号为92
窗口3售出票号为91
窗口3售出票号为90
窗口3售出票号为89
窗口3售出票号为88
窗口3售出票号为87
窗口3售出票号为86
窗口3售出票号为85
窗口3售出票号为84
窗口3售出票号为83
窗口3售出票号为82
窗口3售出票号为81
窗口3售出票号为80
窗口3售出票号为79
窗口3售出票号为78
窗口3售出票号为77
窗口3售出票号为76
窗口3售出票号为75
窗口3售出票号为74
窗口3售出票号为73
窗口3售出票号为72
窗口3售出票号为71
窗口3售出票号为70
窗口3售出票号为69
窗口3售出票号为68
窗口3售出票号为67
窗口3售出票号为66
窗口3售出票号为65
窗口3售出票号为64
窗口3售出票号为63
窗口3售出票号为62
窗口3售出票号为61
窗口3售出票号为60
窗口3售出票号为59
窗口3售出票号为58
窗口3售出票号为57
窗口3售出票号为56
窗口3售出票号为55
窗口3售出票号为54
窗口3售出票号为53
窗口3售出票号为52
窗口3售出票号为51
窗口3售出票号为50
窗口3售出票号为49
窗口3售出票号为48
窗口3售出票号为47
窗口3售出票号为46
窗口3售出票号为45
窗口3售出票号为44
窗口3售出票号为43
窗口3售出票号为42
窗口3售出票号为41
窗口3售出票号为40
窗口3售出票号为39
窗口3售出票号为38
窗口3售出票号为37
窗口3售出票号为36
窗口3售出票号为35
窗口3售出票号为34
窗口3售出票号为33
窗口3售出票号为32
窗口3售出票号为31
窗口3售出票号为30
窗口3售出票号为29
窗口3售出票号为28
窗口3售出票号为27
窗口3售出票号为26
窗口3售出票号为25
窗口3售出票号为24
窗口3售出票号为23
窗口3售出票号为22
窗口3售出票号为21
窗口3售出票号为20
窗口3售出票号为19
窗口3售出票号为18
窗口3售出票号为17
窗口3售出票号为16
窗口3售出票号为15
窗口3售出票号为14
窗口3售出票号为13
窗口3售出票号为12
窗口3售出票号为11
窗口3售出票号为10
窗口3售出票号为9
窗口3售出票号为8
窗口3售出票号为7
窗口3售出票号为6
窗口3售出票号为5
窗口3售出票号为4
窗口3售出票号为3
窗口3售出票号为2
窗口3售出票号为1
明显线程是安全的!!
}
线程安全的原因 :线程安全是由于多个线程在数据共享过程中出现了异常,比如一个线程还未执行完成,另一个线程就参与了进来,导致共享的数据不准确。那么我们如何来解决线程安全问题呢?方法有多种 笔者就先列举一种方法叫"安全代码块"关键代码synchronized 具体例子如下:
方式一: 安全代码块,用关键代码synchronized包围代码块,该方法的锁为this
1.class SaleTicket implements Runnable{
static int ticket=100;//静态变量
public void run(){
while(true){
synchronized(this){//this指SaleTicket
if(ticket>0){
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"售出票号为"+ ticket--);
}
}
}
public static void main(String[] args) {
SaleTicket saler1=new SaleTicket();
Thread t1=new Thread(saler1);
Thread t2=new Thread(saler1);
Thread t3=new Thread(saler1);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
方式二:安全方法 用synchronized声明方法 该方法的锁为this即为当前对象
public void run() {
show();
}
public synchronized void show(){
while(true){
if(ticket>0){
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"售出票号为"+ ticket--);
}
}
2.输出结果一样为:
窗口2售出票号为100
窗口3售出票号为99
窗口3售出票号为98
窗口3售出票号为97
窗口3售出票号为96
窗口3售出票号为95
窗口3售出票号为94
窗口3售出票号为93
窗口3售出票号为92
窗口3售出票号为91
窗口3售出票号为90
窗口3售出票号为89
窗口3售出票号为88
窗口3售出票号为87
窗口3售出票号为86
窗口3售出票号为85
窗口3售出票号为84
窗口3售出票号为83
窗口3售出票号为82
窗口3售出票号为81
窗口3售出票号为80
窗口3售出票号为79
窗口3售出票号为78
窗口3售出票号为77
窗口3售出票号为76
窗口3售出票号为75
窗口3售出票号为74
窗口3售出票号为73
窗口3售出票号为72
窗口3售出票号为71
窗口3售出票号为70
窗口3售出票号为69
窗口3售出票号为68
窗口3售出票号为67
窗口3售出票号为66
窗口3售出票号为65
窗口3售出票号为64
窗口3售出票号为63
窗口3售出票号为62
窗口3售出票号为61
窗口3售出票号为60
窗口3售出票号为59
窗口3售出票号为58
窗口3售出票号为57
窗口3售出票号为56
窗口3售出票号为55
窗口3售出票号为54
窗口3售出票号为53
窗口3售出票号为52
窗口3售出票号为51
窗口3售出票号为50
窗口3售出票号为49
窗口3售出票号为48
窗口3售出票号为47
窗口3售出票号为46
窗口3售出票号为45
窗口3售出票号为44
窗口3售出票号为43
窗口3售出票号为42
窗口3售出票号为41
窗口3售出票号为40
窗口3售出票号为39
窗口3售出票号为38
窗口3售出票号为37
窗口3售出票号为36
窗口3售出票号为35
窗口3售出票号为34
窗口3售出票号为33
窗口3售出票号为32
窗口3售出票号为31
窗口3售出票号为30
窗口3售出票号为29
窗口3售出票号为28
窗口3售出票号为27
窗口3售出票号为26
窗口3售出票号为25
窗口3售出票号为24
窗口3售出票号为23
窗口3售出票号为22
窗口3售出票号为21
窗口3售出票号为20
窗口3售出票号为19
窗口3售出票号为18
窗口3售出票号为17
窗口3售出票号为16
窗口3售出票号为15
窗口3售出票号为14
窗口3售出票号为13
窗口3售出票号为12
窗口3售出票号为11
窗口3售出票号为10
窗口3售出票号为9
窗口3售出票号为8
窗口3售出票号为7
窗口3售出票号为6
窗口3售出票号为5
窗口3售出票号为4
窗口3售出票号为3
窗口3售出票号为2
窗口3售出票号为1
明显线程是安全的!!
}
相关文章推荐
- Mac Maven java_home错误
- Java内功提升之类与对象
- 基础算法 快速排序
- 八大排序算法的Java实现
- java利用过滤器实现编码的转换,内容输出的替换
- 最简单的spring的例子
- JAVA创建XML文件(一)---DOM方式创建XML
- java批量命名文件名
- java中的对象为什么需要序列化,什么时候要序列化
- 基础算法 冒泡排序
- java中Date类详解
- 【Android】一步一步教你从Eclipse移植项目到Android Studio(1.4)
- java中Clendar类详解
- JAVA线程:
- java.lang.Math
- 从头认识java-10.6 finally(3)-异常的丢失
- mysql与sqlsever 2008 链接java步骤以及问题解决方案
- 使用 Arrays 类操作 Java 中的数组
- java final修饰成员变量赋值的二种方法
- jdk生成Webservice客户端方法