Thread的小基础(二)

线程同步

 

为什么需要“线程同步”

线程间共享代码和数据可以节省系统开销,提高程序运行效率,

但同时也导致了数据的“访问冲突”问题,

如何实现线程间的有机交互、并确保共享资源在某些关键时段只能被一个线程访问,即所谓的“线程同步”(Synchronization)就变得至关重要。

 

 

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

用在对象前面限制一段代码的执行(同步代码块)
public void push(char c){
  …
  sychronized(this){
     data[index]=c;
     index++
  }
}

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

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

 

 

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

同步弊端

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

同步嵌套,容易出现死锁

 

 

 

/*

同步的两种表现形式:

1,同步代码块:需要一个锁。

2,同步函数:问:同步函数用的是哪个锁呢?

 

需求:将售票程序通过同步函数的形式解决一下线程安全问题。

 

 

*/

 

class SaleTicket implements Runnable

{

   privateint tick = 100;

 

   public  void run()

   {

      while(true)

      {       

         show();

      }

   }

 

   publicsynchronized void show()

   {

      if(tick>0)

      {

         try{Thread.sleep(100);}catch(Exceptione){}

         System.out.println(Thread.currentThread().getName()+".....sale......"+tick--);

      }

   }

}

 

class ThreadDemo6

{

   publicstatic void main(String[] args)

   {

     

      SaleTickett = new SaleTicket();

     

      Threadt1 = new Thread(t);

      Threadt2 = new Thread(t);

      Threadt3 = new Thread(t);

      Threadt4 = new Thread(t);

 

      t1.start();

      t2.start();

      t3.start();

      t4.start();

   }

}

 

 

下面线程同步的售票应用:

package cn.csdn.hr.thread;

 

publicclass Sale {

 

   /**

    * 售票的应用

    * @param args

    */

   publicstaticvoid main(String[] args){

       Ticket t = new Ticket();

       Thread t1 =new Thread(t);

       Thread t2 =new Thread(t);

       t1.start();

       t2.start();

   }

 

}

class Ticketimplements Runnable{

   privateints= 100;

   Object obj = new Object();

   @Override

   publicvoid run(){

         while(true){

             show();

         }

             

           /*if(s>0){

               try{

                   Thread.sleep(100);

               }catch (InterruptedException e) {

                   //TODO Auto-generatedcatch block

                   e.printStackTrace();

               }

            System.out.println(Thread.currentThread().getName()+"....."+s--);

               }*/

            

        }

   

   

   

   

       publicsynchronizedvoid show(){

           if(s>0){

               try {

                   Thread.sleep(100);

               } catch(InterruptedException e) {

                   // TODO Auto-generatedcatch block

                   e.printStackTrace();

               }

             System.out.println(Thread.currentThread().getName()+"....."+s--);

               }

 

   }

   

}

 

 

 

 

/**

 *同步的两种方法:

 *

 * 1.

 *

 * synchronized (对象){

 *   同步的代码块

 * }

 *

 * 2.采用函数的方法:使用的锁是 this

 *    public synchronized void show(){//同步函数

 *     同步的代码块

 *    }

 *

 *

 *

 *单例模式:

 *懒汉式:结合线程的应用

 *同步对象

 * class Single{

 *    private static Single s = null;

 *    private Single(){}

 *    public static  Single getInstance(){

 *       if(s==null){

 *       synchronized(Single.class){

 *         if(s==null){

 *          s = new Single();

 *          }

 *       }

 *       return s;

 *      

 *    }

 *

 *

 *同步函数

 * class Single{

 *    private static Single s = null;

 *    private Single(){}

 *    public static synchronized SinglegetInstance(){

 *       if(s==null){

 *       s = new Single();

 *       return s;

 *       }

 *      

 *    }

 *饿汉式:

 * class Single{

 *    private static Single s = new Single();

 *    private Single(){}

 *    public static Single getInstance(){

 *       return s;

 *    }

 * }

 */

   

 

 

第二个事例:

package cn.csdn.hr.thread;

class Tickets{

   publicinttickets;

 

   public Tickets() {

       

       tickets = 10;

   }

   publicsynchronizedvoid action(String name){

       System.out.println(name+"卖了"+tickets+"张");

       tickets--;

   }

   

}

 

class TicketsThreadextends Thread{

   Tickets t;

   String name;

   publicTicketsThread(Tickets t, String name) {

       

       this.t = t;

       this.name = name;

       start();

   }

   public void run(){

            try{

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

                   t.action(name);

                   Thread.sleep(20);

           }

           }catch(Exception e){}

   }

}

publicclass TestThread {

 

   /**

    * 售票

    * @param args

    */

   publicstaticvoid main(String[] args){

       Tickets t =new Tickets();

       TicketsThreadd1 = new TicketsThread(t,"我");

       TicketsThreadd2 = new TicketsThread(t,"你");

   }

 

}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值