Java多线程(2)——多线程安全(传智播客毕老师视频讲解)
来源:互联网 发布:软件测试工具使用 编辑:程序博客网 时间:2024/05/16 19:54
有如下代码
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这儿锁死了,两个线程所持有的锁都不让对方进入,做开发时一定要避免死锁的出现!!
0 0
- Java多线程(2)——多线程安全(传智播客毕老师视频讲解)
- Java多线程(1)——多线程创建(传智播客毕老师视频讲解)
- Java多线程(3)——多线程通信(传智播客毕老师视频讲解)
- Java多线程(4)——多线程JDK5.0升级版(传智播客毕老师视频讲解)
- Java多线程(5)——多线程停止(传智播客毕老师视频讲解)
- Java多线程(6)——Thread类中的一些方法(传智播客毕老师视频讲解)
- Java中Collection子接口(2)——Set接口(传智播客毕老师视频讲解)
- Java中泛型(2)——泛型类(传智播客毕老师视频讲解)
- Java中IO流(2)——字符流(传智播客毕老师视频讲解)
- Java中Collection子接口(1)——List接口(传智播客毕老师视频讲解)
- Java中泛型(1)——泛型介绍(传智播客毕老师视频讲解)
- Java中泛型(3)——泛型方法(传智播客毕老师视频讲解)
- Java中泛型(4)——泛型接口(传智播客毕老师视频讲解)
- Java中泛型(5)——泛型限定(传智播客毕老师视频讲解)
- Java中IO流(1)——IO流概述(传智播客毕老师视频讲解)
- Java中IO流(3)——字符流缓冲区(传智播客毕老师视频讲解)
- Java中IO流(4)——字节流(传智播客毕老师视频讲解)
- Java中IO流(5)——字节流缓冲区(传智播客毕老师视频讲解)
- 实现背景颜色(backgroundColor)的动画效果(animate)
- [Python]解释器的几种实现版本
- USACO 40 The Perfect Stall
- STL algorithm算法fill_n(15)
- 有用的链接(数据获取、项目管理)
- Java多线程(2)——多线程安全(传智播客毕老师视频讲解)
- hibernate4.3 与JPA结合实现数据库插入报错unable to build factory
- ios 使用 通讯录 picker 快速 拾取 用户 手机号码 代码分享
- Java将Unix时间戳转换成指定格式日期
- 互斥量和信号量的区别
- DELPHI之关于String的内存分配
- QT实现CRC16校验(查表法)
- [leetcode] Single Number II
- Linux线程同步与互斥