线程安全问题
1 /* 2 * 线程安全问题 3 * 利用到static的共享情况 4 * 5 * 6 * 1.存在两个或者两个以上的线程 7 * 2.线程共同争夺共享资源 8 * 3.存在多个语句操作共享资源 9 * 10 * 解决方案: 11 * 线程同步机制: 12 * 方式一:同步代码块 推荐使用 13 * synchronized(锁对象){ 14 * 需要同步的代码 15 * } 16 * //--1.任意一个对象都可以作为锁对象,锁对象必须是唯一共享的! 17 * //--2.只有真正存在线程问题的时候才使用代码块,否则会降低效率,,,利用上面的可能出现线程安全来判断 18 * //--3.这个任意对象必须是静态的,因为这样才能为同一个对象.没有static就是三个对象了! 19 * //--4.也可以使用"锁" 这种字符串来作为锁,这是最简单的锁,因为这个是在静态池中的! 20 * 21 * 22 * 23 * 方式二:同步函数: 24 * 使用synchronized修饰的函数 25 * 直接 public synchronized void run() 这样使用 26 * 同步函数要注意的事项: 27 * 1.如果是一个非静态的同步函数,锁对象是this对象;如果是静态的同步函数,锁对象是当前的class对象,即共享对象 28 * 2.锁对象是固定的 29 * 30 */ 31 32 static int num = 50; // 一共五十张票,要利用静态static! 若是非静态的话,是每个对象有一份这样的票数! 33 34 static Object o = new Object(); 35 public Demo6(String name){ 36 super(name); 37 } 38 39 @Override 40 public void run() { 41 while (true) { 42 synchronized (o) { 43 if (num > 0) { 44 System.out.println(Thread.currentThread().getName()+"卖出的票为" + num + "号"); 45 num--; 46 } else { 47 System.out.println("票已经卖完......"); 48 break; 49 } 50 } 51 } 52 } 53 54 public static void main(String[] args) { 55 //三个窗口卖票 56 Demo6 ck1 = new Demo6("窗口一"); 57 Demo6 ck2 = new Demo6("窗口二"); 58 Demo6 ck3 = new Demo6("窗口三"); 59 60 //开启售票多线程 61 ck1.start(); 62 ck2.start(); 63 ck3.start(); 64 }
死锁现象
1 2 /* 3 死锁: 4 例子 张三有遥控器 没电池 ; 李四有电池 没遥控器,两人要去开空调 5 6 原因: 7 1.存在两个或两个以上的线程 8 2.存在两个或者两个以上的共享资源 9 10 无解决方案,只能尽量避免存在! 11 */ 12 13 public Demo7(String name){ 14 super(name); 15 } 16 17 @Override 18 public void run() { 19 if ("张三".equals(Thread.currentThread().getName())) { 20 synchronized ("遥控器") { 21 System.out.println("张三得到遥控器,准备去拿电池"); 22 synchronized ("电池") { 23 System.out.println("张三得到遥控器和电池,开了空调"); 24 } 25 } 26 }else if("李四".equals(Thread.currentThread().getName())){ 27 synchronized ("电池") { 28 System.out.println("李四有电池,准备去拿遥控器"); 29 synchronized ("遥控器") { 30 System.out.println("李四得到遥控器和电池,开了空调"); 31 } 32 } 33 } 34 35 } 36 37 public static void main(String[] args) { 38 Demo7 d1 = new Demo7("张三"); 39 Demo7 d2 = new Demo7("李四"); 40 d1.start(); 41 d2.start(); 42 }