浅谈同步

浅谈同步

    1.为什么需要“线程同步”

         线程间共享代码和数据虽然可以节省系统开销,提高程序运行效率,但同时也导致了数据的“访问冲突”问题,如何实现线程间的有机交互、并确保共享资源在某些关键时段只能被一个线程访问,即所谓的“线程同步”(Synchronization)就变得至关重要。

   2. 临界资源

    多个线程间共享的数据称为临界资源(CriticalResource),由于是线程调度器负责线程的调度,程序员无法精确控制多线程的交替顺序。因此,多线程对临界资源的访问有时会导致数据的不一致性即(出现线程的安全隐患)。

  

  例:一售票系统工作

 

  package csdn.java.thread;

 

publicclass TestMulThread {

 

    /**

     * @param args

     */

    publicstaticvoid main(String[] args) {

       Tickets t = new Tickets();

      

        TicketsThread tt= new TicketsThread("北京",t);

        TicketsThread tt1= new TicketsThread("青年",t);

     

    }

 

}

class Tickets{

 

    publicintticket ;

    public Tickets(){

       this.ticket = 10;

   

    }

    publicsynchronizedvoid show(String name){

       System.out.println("name"+name+"..."+"抢购了the"+ticket+"张票");

       ticket--;

    }

}

class TicketsThread extends Thread{

    String name;

    Tickets t;

   

    public TicketsThread(String name,Tickets t){

       this.name =name;

       this.t =t;

       start();

    }

    publicvoid run(){

   

           for(int i=0;i<5;i++){

              t.show(name);

              try {

                  Thread.sleep(1000);

              } catch (InterruptedException e) {

                  // TODO Auto-generatedcatch block

                  e.printStackTrace();

              }

          

       }

    }

}

3. 互斥锁

每个对象都对应于一个可称为互斥锁的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。

Java对象默认是可以被多个线程共用的,只是在需要时才启动互斥锁机制,成为专用对象。

         /'sɪŋkrənaɪz /

关键字synchronized用来与对象的互斥锁联系

 

当某个对象用synchronized修饰时,表明该对象已启动互斥锁机制,在任一时刻只能由一个线程访问,即使该线程出现堵塞,该对象的被锁定状态也不会解除,其他线程任不能访问该对象。

   

    synchronized关键字的使用方式有两种:

ü       用在对象前面限制一段代码的执行(同步代码块

ü       同步代码块可以使用任意对象作为锁,同步方法使用的锁只有一个--this。static同步方法使用的锁是该方法所属类的对象。类型.class

ü      
public void push(char c){
      …
      sychronized(this){
             data[index]=c;
             index++
      }
}

ü      用在方法声明中,表示整个方法为同步方法

                              public synchronizedchar pop(){

                                       index--;

                                   return data[index];

}

 

      同步好处:决了线程安全问题

同步弊端

ü       降低了运行效率(判断锁是较为消耗资源的)

ü       同步嵌套,容易出现死锁

4.死锁

  两个线程A、B用到同一个对象s(s为共享资源),且线程A在执行中要用到B运行后所创造的条件。在这种前提下A先开始运行,进入同步块后,对象s被锁定,接着线程A因等待B运行结束而进入阻塞状态,于是B开始运行,但因无法访问对象s,线程B也进入阻塞状态,等待s被线程A解锁。最终的结果:两个线程互相等待,都无法运行。

如:

 

 

 

public class DeadLock {

 

   /**

    * @param args

    */

   public static voidmain(String[] args) {

          Demo6 d1=newDemo6(true);

          Demo6 d2=newDemo6(false);

          Thread t1=newThread(d1);

          Thread t2=newThread(d2);

          t1.start();

          t2.start();

 

   }

 

}

 

class MyLock{

   static MyLock lock1=newMyLock();

   static MyLock lock2=newMyLock();

  

}

 

class Demo6 implements Runnable{

   //String str1=newString("aaa");

   //String str2=new String("bbb");

  

   private boolean flag;

   public Demo6(boolean flag){

          this.flag=flag;

   }

 

   @Override

   public void run() {

          if(flag){

                 synchronized(MyLock.lock1){

                        System.out.println(Thread.currentThread().getName()+"...if...str1");     

                       

                        synchronized(MyLock.lock2){

                               System.out.println(Thread.currentThread().getName()+"...if...str2");

                              

                        }

                 }

                

                

          }else{

            synchronized(MyLock.lock2){

                   System.out.println(Thread.currentThread().getName()+"...else...str2");

                 

                         synchronized(MyLock.lock1){

                               System.out.println(Thread.currentThread().getName()+"...else...str1");

                        }

                 }

          }

         

   }

  

}

 

  这是线程死锁的典型表现,两个以上线程并发运行,他们均因其他线程锁定了自己运行所需资源而陷入阻塞状态,同时自己也锁定了其他线程所需资源。

 

分析:子线程t并未锁定任何共享资源,只是因为无法访问共享资源sb而陷入阻塞状态。主线程则是因为串行加入了子线程t而进入阻塞状态,且必须要等线程t运行完毕才可能恢复运行并解除对共享资源的锁定,双方僵持、互不相让,导致进入“死锁”状态。

 

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值