一个多线程的程序如果是通过 Runnable 接口实现的,则意味着类中的属性被多个线程共享,那么这样就会造成一种问题,如果这多个线程要操作同一个资源时就有可能出现资源同步问题。
同步代码块
synchronized(同步对象){ 需要同步的代码 }
|
class MyThread implements Runnable{ private int ticket = 5 ; public void run(){ for(int i=0;i<100;i++){ synchronized(this){ if(ticket>0){ try{ Thread.sleep(300) ; }catch(InterruptedException e){ e.printStackTrace() ; } System.out.println("卖票:ticket = " + ticket-- ); } } } } }; public class SyncDemo02{ public static void main(String args[]){ MyThread mt = new MyThread() ; Thread t1 = new Thread(mt) ; Thread t2 = new Thread(mt) ; Thread t3 = new Thread(mt) ; t1.start() ; t2.start() ; t3.start() ; } };
|
程序执行结果:
同步方法
除了可以将需要的代码设置成同步代码块外,也可以使用 synchronized 关键字将一个方法声明为同步方法。
synchronized 方法返回值 方法名称(参数列表){
}
|
class MyThread implements Runnable{ private int ticket = 5 ; public void run(){ for(int i=0;i<100;i++){ this.sale() ; } } public synchronized void sale(){ if(ticket>0){ try{ Thread.sleep(300) ; }catch(InterruptedException e){ e.printStackTrace() ; } System.out.println("卖票:ticket = " + ticket-- ); }
} }; public class SyncDemo03{ public static void main(String args[]){ MyThread mt = new MyThread() ; Thread t1 = new Thread(mt) ; Thread t2 = new Thread(mt) ; Thread t3 = new Thread(mt) ; t1.start() ; t2.start() ; t3.start() ; } };
|
程序执行结果:
从程序运行的结果可以发现,此代码完成了与之前同步代码同样的功能。
死锁
同步可以保证资源共享操作的正确性,但是过多同步也会产生问题。例如,现在张三想要李四的画,李四想要张三的书,张三对李四说“把你的画给我,我就给你书”,李四也对张三说“把你的书给我,我就给你画”两个人互相等对方先行动,就这么干等没有结果,这实际上就是死锁的概念。
所谓死锁,就是两个线程都在等待对方先完成,造成程序的停滞,一般程序的死锁都是在程序运行时出现的。
下面以一个简单范例说明这个概念
class Zhangsan{ public void say(){ System.out.println("张三对李四说:“你给我画,我就把书给你。”") ; } public void get(){ System.out.println("张三得到画了。") ; } }; class Lisi{ public void say(){ System.out.println("李四对张三说:“你给我书,我就把画给你”") ; } public void get(){ System.out.println("李四得到书了。") ; } }; public class ThreadDeadLock implements Runnable{ private static Zhangsan zs = new Zhangsan() ; private static Lisi ls = new Lisi() ; private boolean flag = false ; public void run(){ if(flag){ synchronized(zs){ zs.say() ; try{ Thread.sleep(500) ; }catch(InterruptedException e){ e.printStackTrace() ; } synchronized(ls){ zs.get() ; } } }else{ synchronized(ls){ ls.say() ; try{ Thread.sleep(500) ; }catch(InterruptedException e){ e.printStackTrace() ; } synchronized(zs){ ls.get() ; } } } } public static void main(String args[]){ ThreadDeadLock t1 = new ThreadDeadLock() ; ThreadDeadLock t2 = new ThreadDeadLock() ; t1.flag = true ; t2.flag = false ; Thread thA = new Thread(t1) ; Thread thB = new Thread(t2) ; thA.start() ; thB.start() ; } };
|
程序运行结果:
以下代码不再执行,程序进入死锁状态。