线程同步锁对象不同导致的安全问题及解决办法
来源:互联网 发布:免费网络电话软件排名 编辑:程序博客网 时间:2024/05/18 05:40
线程同步锁的对象有三个:
1)、objcet对象
2)、this对象
3)、class文件对象
总结:
线程同步锁对象是this,若是静态函数,则是类名.class
1、若对一个对象的共享代码进行同步锁时,若使用不同的锁,存在线程安全问题
例如:
<pre name="code" class="java">class Ticket implements Runnable{private String name;private int ticket=20;boolean flag;Object obj = new Object();Ticket(String name){this.name = name;}public void run(){if(flag==true){while(true){//如下同步的锁对象是objcetsynchronized(obj){if(ticket > 0){try{Thread.sleep(10);}catch(InterruptedException e){}System.out.println(Thread.currentThread().getName()+" "+name+"code..."+ticket--);}}}}elsewhile(true){show();}}//如下函数同步的锁对象是thispublic synchronized void show(){if(ticket > 0){try{Thread.sleep(10);}catch(InterruptedException e){}System.out.println(Thread.currentThread().getName()+" "+name+"show..."+ticket--);}}}public class ThreadDemo {public static void main(String[] args) {Ticket t1 = new Ticket("t1");Thread tt1 = new Thread(t1);Thread tt2= new Thread(t1);tt1.start();try{Thread.sleep(10);}catch(InterruptedException e){}t1.flag=true;tt2.start();}}
运行结果是:
Thread-0 t1show...20Thread-1 t1code...19Thread-0 t1show...18Thread-1 t1code...17Thread-0 t1show...16Thread-1 t1code...15Thread-0 t1show...14Thread-1 t1code...13Thread-0 t1show...12Thread-1 t1code...11Thread-0 t1show...10Thread-1 t1code...9Thread-0 t1show...8Thread-1 t1code...7Thread-0 t1show...6Thread-1 t1code...5Thread-1 t1code...4Thread-0 t1show...3Thread-1 t1code...2Thread-0 t1show...1Thread-1 t1code...0运行结果出现ticket为0的情况,因为同步锁的对象不同,分别是object和this对象
2、若共享操作用的是同一个锁对象,则结果正确,修改后的代码如下:
class Ticket implements Runnable{private String name;private int ticket=20;boolean flag;Object obj = new Object();Ticket(String name){this.name = name;}public void run(){if(flag==true){while(true){//如下同步的锁对象是thissynchronized(this){if(ticket > 0){try{Thread.sleep(10);}catch(InterruptedException e){}System.out.println(Thread.currentThread().getName()+" "+name+"code..."+ticket--);}}}}elsewhile(true){show();}}//如下函数同步的锁对象是thispublic synchronized void show(){if(ticket > 0){try{Thread.sleep(10);}catch(InterruptedException e){}System.out.println(Thread.currentThread().getName()+" "+name+"show..."+ticket--);}}}运行后结果是:
Thread-0 t1code...20Thread-0 t1code...19Thread-0 t1code...18Thread-0 t1code...17Thread-0 t1code...16Thread-0 t1code...15Thread-0 t1code...14Thread-0 t1code...13Thread-0 t1code...12Thread-0 t1code...11Thread-0 t1code...10Thread-0 t1code...9Thread-0 t1code...8Thread-0 t1code...7Thread-0 t1code...6Thread-0 t1code...5Thread-0 t1code...4Thread-0 t1code...3Thread-0 t1code...2Thread-0 t1code...1
3、若共享方法是静态方法时且锁对象是this时,还存在线程安全问题
class Ticket implements Runnable{private String name;private static int ticket=20;boolean flag;Object obj = new Object();Ticket(String name){this.name = name;}public void run(){if(flag==true){while(true){//如下同步的锁对象是objcetsynchronized(obj){if(ticket > 0){try{Thread.sleep(10);}catch(InterruptedException e){}System.out.println(Thread.currentThread().getName()+" "+name+"code..."+ticket--);}}}}elsewhile(true){show();}}public static synchronized void show(){if(ticket > 0){try{Thread.sleep(10);}catch(InterruptedException e){}System.out.println(Thread.currentThread().getName()+" "+name+"show..."+ticket--);}}}public class ThreadDemo {public static void main(String[] args) {Ticket t1 = new Ticket("t1");Thread tt1 = new Thread(t1);Thread tt2= new Thread(t1);tt1.start();try{Thread.sleep(10);}catch(InterruptedException e){}t1.flag=true;tt2.start();}}运行结果是:
Thread-0 t1show...20Thread-1 t1code...19Thread-0 t1show...18Thread-1 t1code...17Thread-0 t1show...16Thread-1 t1code...15Thread-0 t1show...14Thread-1 t1code...13Thread-0 t1show...12Thread-1 t1code...11Thread-0 t1show...10Thread-1 t1code...9Thread-0 t1show...8Thread-1 t1code...7Thread-0 t1show...6Thread-1 t1code...5Thread-1 t1code...4Thread-0 t1show...3Thread-1 t1code...2Thread-0 t1show...1Thread-1 t1code...0分析原因后发现:静态函数在内存中不存在,但是有该类对应的字节码文件
优化后的代码是:
class Ticket implements Runnable{private String name;private static int ticket=20;boolean flag;Object obj = new Object();Ticket(String name){this.name = name;}public void run(){if(flag==true){while(true){//如下同步的锁对象是<span style="font-family: Arial, Helvetica, sans-serif;">Ticket.class</span>synchronized(Ticket.class){if(ticket > 0){try{Thread.sleep(10);}catch(InterruptedException e){}System.out.println(Thread.currentThread().getName()+" "+name+"code..."+ticket--);}}}}elsewhile(true){show();}}//含有static修饰符的函数同步的锁对象是<span style="font-family: Arial, Helvetica, sans-serif;">Ticket.class</span>public static synchronized void show(){if(ticket > 0){try{Thread.sleep(10);}catch(InterruptedException e){}System.out.println(Thread.currentThread().getName()+" "+name+"show..."+ticket--);}}}public class ThreadDemo {public static void main(String[] args) {Ticket t1 = new Ticket("t1");Thread tt1 = new Thread(t1);Thread tt2= new Thread(t1);tt1.start();try{Thread.sleep(10);}catch(InterruptedException e){}t1.flag=true;tt2.start();}}运行后的结果是:
Thread-0 t1code...20Thread-0 t1code...19Thread-0 t1code...18Thread-0 t1code...17Thread-0 t1code...16Thread-0 t1code...15Thread-0 t1code...14Thread-0 t1code...13Thread-0 t1code...12Thread-0 t1code...11Thread-0 t1code...10Thread-0 t1code...9Thread-0 t1code...8Thread-0 t1code...7Thread-0 t1code...6Thread-0 t1code...5Thread-0 t1code...4Thread-0 t1code...3Thread-0 t1code...2Thread-0 t1code...1
1 0
- 线程同步锁对象不同导致的安全问题及解决办法
- 线程安全问题及解决办法
- java线程的同步安全问题三种解决办法
- 线程同步引发的安全问题
- C#中的线程同步及线程用到的锁对象
- 线程同步及线程用到的锁对象
- 线程的同步与死锁及解决办法
- 过度优化导致的线程安全问题
- 线程同步---线程安全问题
- java基础之多线程的安全问题、同步
- 多线程-4-线程同步、线程安全问题及死锁研究
- java 同对象不同方法线程同步的研究
- JSP不同线程导致对象改变
- Java线程安全问题与同步锁
- 关于同步线程安全问题
- 线程同步的解决办法
- 多线程安全问题及代码的同步
- 黑马程序员------多线程(No.1)(概述、线程的创建、安全问题、同步锁、同步函数)
- Ajax的使用
- 自定义对话框Dialog
- 会场安排问题(贪心算法)
- ios代码大全】代码例子区全区搜索索引
- 枚举
- 线程同步锁对象不同导致的安全问题及解决办法
- 实战剖析三层架构3:不要说BLL没有用
- Property type 'id<xxxxTabBarDelegate>' is incompatible with type 'id<UITabBarDelegate>' inherited fr
- 杨辉三角
- codeforces#280(div2)
- Java 与 C 之间传递数据
- 2014.12.02MySQL
- 编译原理结构框架6语法制导翻译与属性文法
- 【C语言疯狂讲义】(十六)C语言简易通讯录(未优化版)