线程安全问题:
产生线程安全的原因:
1、存在多线程;
2、多个线程操作同一个共享资源;
3、有多行操作共享资源的语句。
解决方案:
使用同步代码解决(synchronized)
package cn.itcast.thread; class SaleTickets extends Thread { static int num = 50; public SaleTickets(String name) { super(name); } @Override public void run() { while(true) { synchronized ("Lock") { if(num > 0) { System.out.println(currentThread().getName() + "售出了" + num-- +"号票。"); } else { System.out.println("售罄了。"); break; } } } } } public class Demo3 { public static void main(String[] args) { SaleTickets thread1 = new SaleTickets("窗口1"); thread1.start(); SaleTickets thread2 = new SaleTickets("窗口2"); thread2.start(); SaleTickets thread3 = new SaleTickets("窗口3"); thread3.start(); } }
如果使用同步函数需要注意:
1、非静态同步函数的锁对象是this,静态函数的锁对象是当前所属类的字节码文件(class对象);
2、同步函数的锁对象是固定的,不能由程序制定。
推荐使用同步代码块,原因:
1、同步代码块的锁对象由开发人员制定,方便控制;
2、同步代码块可以方便的控制同步代码的范围,而同步函数必须是整个函数的所有代码都被同步。
死锁:java同步机制解决了线程安全问题,也同时引发了死锁问题
如下代码会造成死锁现象
package cn.itcast.thread; /*java同步机制解决了线程安全问题,也同时引发了死锁问题*/ class DeadLock extends Thread { public DeadLock(String name) { super(name); } @Override public void run() { if ("张三".equals(currentThread().getName())) { synchronized ("遥控器") { System.out.println("张三拿到了遥控器,准备去电池"); synchronized ("电池") { System.out.println("张三拿到了电池,可以开空调了"); } } } if ("李四".equals(currentThread().getName())) { synchronized ("电池") { System.out.println("李四拿到了电池,准备去拿遥控器"); synchronized ("遥控器") { System.out.println("李四拿到了遥控器,可以开空调了"); } } } } } public class Demo5 { public static void main(String[] args) { DeadLock thread1 = new DeadLock("张三"); DeadLock thread2 = new DeadLock("李四"); thread1.start(); thread2.start(); } }
出现死锁的原因:
1、存在多线程;
2、存在多个(两个或以上)共享资源。
死锁没有具体的解决方案,只能在开发过程中避免死锁的出现!!!