线程同步
当多个线程同时进程一种资源操作,为保证操作的完整性,引入了同步处理。
class MyThread2 implements Runnable{ private int ticket=10; public void run(){ for(int i=0;i<50;i++){ if(this.ticket>0){ System.out.println(Thread.currentThread().getName()+"买票;余票"+this.ticket); this.ticket--; } } } } public class SynDemo1 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub MyThread2 mt1=new MyThread2(); new Thread(mt1,"线程A").start(); new Thread(mt1,"线程B").start(); new Thread(mt1,"线程C").start(); } }
但是,从实际的操作看,都使用网络卖票,则有可能出现网络延迟
class MyThread2 implements Runnable{ private int ticket=10; public void run(){ for(int i=0;i<50;i++){ if(this.ticket>0){ try{ Thread.sleep(300); } catch (Exception e){} System.out.println(Thread.currentThread().getName()+"买票;余票"+this.ticket); this.ticket--; } } } } public class SynDemo1 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub MyThread2 mt1=new MyThread2(); new Thread(mt1,"线程A").start(); new Thread(mt1,"线程B").start(); new Thread(mt1,"线程C").start(); } }
本程序中可以发现一旦加入了延迟之后,买出的票数就不准确了。
由于现在是有多个线程操作,那么最好的解决方法是加入一个锁的标记,锁标记中将判断和修改同时进行,要想完成这种锁的程序可以通过两种语句实现,同步代码块,同步方法。
class MyThread2 implements Runnable{ private int ticket=10; public void run(){ for(int i=0;i<50;i++){ this.sale(); } } public synchronized void sale(){ if(this.ticket>0){ try{ Thread.sleep(300); } catch (Exception e){} System.out.println(Thread.currentThread().getName()+"买票;余票"+this.ticket); this.ticket--; } } //代码块同步
/*public void run(){ for(int i=0;i<50;i++){ synchronized(this){ if(this.ticket>0){ try{ Thread.sleep(300); } catch (Exception e){} System.out.println(Thread.currentThread().getName()+"买票;余票"+this.ticket); this.ticket--; } } } }*/ } public class SynDemo1 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub MyThread2 mt1=new MyThread2(); new Thread(mt1,"线程A").start(); new Thread(mt1,"线程B").start(); new Thread(mt1,"线程C").start(); } }