Java多线程(2)——多线程安全(传智播客毕老师视频讲解)
2014-09-11 12:33
519 查看
有如下代码
发现有两个10,且其排序不是按照从大到小输出的,此时这种情况属于多线程安全问题。其原因主要是线程0和线程1抢夺执行权引起的,
即当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据
的错误。
解决办法:对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可参与执行!
1、同步
同步的前提:1、必须要有两个或者两个以上的线程。
2、必须是多个线程使用同一个锁。
方法1、同步代码块
synchonized(对象)//对象如同锁。持有锁的线程可以在同步中执行;没有锁的线程即使获取CPU执行权,也进不去。
{
需要被同步的代码
}
看见,此时结果没问题。
方法2、同步函数
运行结果如下:
注意:1、同步函数用的锁是this!
2、静态同步函数用的锁是Class对象!
由于静态方法中不能出现this、super关键字,因此其锁不能为this,但可以是任意class对象!
验证代码如下:
方法1、同步函数
即结果在97这儿锁死了,两个线程所持有的锁都不让对方进入,做开发时一定要避免死锁的出现!!
public class RunnableDemo2 implements Runnable { int i=10; public void run() { for(;i>0;i--) System.out.println("...."+Thread.currentThread().getName()+"...."+i); } } public class Xian1 { static int i; public static void main(String[] args) { RunnableDemo2 t =new RunnableDemo2(); Thread t1=new Thread(t); Thread t2=new Thread(t); t1.start(); t2.start(); for(i=0;i<5;i++) { System.out.println("...main......"+Thread.currentThread().getName()); } System.out.println("over"); } }运行结果如下:
发现有两个10,且其排序不是按照从大到小输出的,此时这种情况属于多线程安全问题。其原因主要是线程0和线程1抢夺执行权引起的,
即当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据
的错误。
解决办法:对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可参与执行!
1、同步
同步的前提:1、必须要有两个或者两个以上的线程。
2、必须是多个线程使用同一个锁。
方法1、同步代码块
synchonized(对象)//对象如同锁。持有锁的线程可以在同步中执行;没有锁的线程即使获取CPU执行权,也进不去。
{
需要被同步的代码
}
public class RunnableDemo2 implements Runnable { int i=10; public void run() { synchronized(this) { for(;i>0;i--) System.out.println("...."+Thread.currentThread().getName()+"...."+i); } } }运行结果如下:
看见,此时结果没问题。
方法2、同步函数
public class RunnableDemo2 implements Runnable { int i=10; public void run() { while(i>0) show(); } public synchronized void show() { try{Thread.sleep(100);}catch(Exception e){} if(i>0) System.out.println("...."+Thread.currentThread().getName()+"...."+i--); } }
运行结果如下:
注意:1、同步函数用的锁是this!
2、静态同步函数用的锁是Class对象!
由于静态方法中不能出现this、super关键字,因此其锁不能为this,但可以是任意class对象!
验证代码如下:
public class RunanbleDemo implements Runnable { static int i=100; boolean flag=true; Object obj=new Object(); public void setValue(boolean flag) { this.flag=flag; } public void run() { if (flag) { while(true) { synchronized(this) //验证非静态同步函数的锁是this //synchronized(RunanbleDemo.class)//验证静态同步函数的锁是Class文件 {//同步代码块儿 while(i>0) { try{Thread.sleep(10);}catch(Exception e){} //try{wait();}catch(Exception e){} System.out.println("...."+Thread.currentThread().getName()+"...."+"Code"+"...."+i--); } } } } else { while(true) show(); } } public synchronized void show() //非静态同步函数 //public synchronized static void show()//静态同步函数 { if(i>0) { try{Thread.sleep(10);}catch(Exception e){} System.out.println("...."+Thread.currentThread().getName()+"..............."+"Show"+"...."+i--); } } } public class Xian1 { static int i; public static void main(String[] args) { RunanbleDemo t =new RunanbleDemo(); Thread t1=new Thread(t); Thread t2=new Thread(t); t1.start(); try{Thread.sleep(10);}catch(Exception e){} t.setValue(false); t2.start(); System.out.println("over"); } }2、单例设计模式——懒汉式的多线程安全问题
方法1、同步函数
public class Single { private static Single s=null; private Single(){} public static synchronized Single getSingle() { if (s==null) s=new Single(); return s; } }方法2、同步代码块(优化版)
public class Single { private static Single s=null; private Single(){} public static Single getSingle() { if (s==null) //这是其优化的地方,这样保证假如许多线程进来,减少了判断syncronized的过程,优化了代码 synchronized(Single.class) { if (s==null) s=new Single(); } return s; } }3、死锁
public class DeadLock implements Runnable { static int i=100; boolean flag=true; Object obj=new Object(); public void setValue(boolean flag) { this.flag=flag; } public void run() { if (flag) { while(true) { synchronized(DeadLock.class) { synchronized(this) //验证非静态同步函数的锁是this { if(i>0) { try{Thread.sleep(10);}catch(Exception e){} System.out.println("...."+Thread.currentThread().getName()+"...."+"Code"+"...."+i--); } } } } } else { while(true) { synchronized(this) { synchronized(DeadLock.class) { if(i>0) { try{Thread.sleep(10);}catch(Exception e){} System.out.println("...."+Thread.currentThread().getName()+"..............."+"Show"+"...."+i--); } } } } } } } public class DeadLockDemo { static int i; public static void main(String[] args) { DeadLock t =new DeadLock(); Thread t1=new Thread(t); Thread t2=new Thread(t); t1.start(); try{Thread.sleep(10);}catch(Exception e){} t.setValue(false); t2.start(); System.out.println("over"); } }运行结果为:
即结果在97这儿锁死了,两个线程所持有的锁都不让对方进入,做开发时一定要避免死锁的出现!!
相关文章推荐
- Java多线程(3)——多线程通信(传智播客毕老师视频讲解)
- Java多线程(4)——多线程JDK5.0升级版(传智播客毕老师视频讲解)
- Java多线程(1)——多线程创建(传智播客毕老师视频讲解)
- Java中String类(传智播客毕老师视频讲解)
- Java中Collection子接口(1)——List接口(传智播客毕老师视频讲解)
- Java中集合框架工具类——Arrays(传智播客毕老师视频讲解)
- Java中IO流(2)——字符流(传智播客毕老师视频讲解)
- Java中System类(传智播客毕老师视频讲解)
- Java中增强for循环(传智播客毕老师视频讲解)
- Java中泛型(5)——泛型限定(传智播客毕老师视频讲解)
- Java中IO流(1)——IO流概述(传智播客毕老师视频讲解)
- Java多线程(5)——多线程停止(传智播客毕老师视频讲解)
- Java中Collection子接口(2)——Set接口(传智播客毕老师视频讲解)
- Java中基本数据类型对象包装类(传智播客毕老师视频讲解)
- Java中可变参数方法(传智播客毕老师视频讲解)
- Java对象初始化过程(传智播客毕老师视频讲解)
- Java中IO流(5)——字节流缓冲区(传智播客毕老师视频讲解)
- Java中泛型(1)——泛型介绍(传智播客毕老师视频讲解)
- Java中Runtime类(传智播客毕老师视频讲解)
- Java中静态导入(传智播客毕老师视频讲解)