synchroized关键字使用说明,重温卖票经典案例

   synchroized关键字总结:
      类锁:
         synchronized(类.class){…}
         synchronized修饰静态方法
      对象锁:
         synchronized(this){…}
         synchronized(自定义内部对象实例){…}
         synchronized修饰普通方法
   使用对象锁的情况:所有的线程共用一个对象实例才会保证线程安全.我的理解是同一对象实例才能保证锁是唯一.
   使用类锁的情况:是所有线程共享的锁(就是所有线程共享一把类锁),所以同一时刻,只能有一个线程使用加了锁的方法或方法体,不管是不是同一个实例都只允许一个线程访问.
   卖票问题解决方案:
1.使用synchroized锁对象:
1.1使用this关键字:
售票类:

public class SaleTicket {
    
    
    private static int ticketCount=100;

    public void saleTicket(){
    
    
     while (ticketCount>0){
    
    
         // 锁对象:synchronized (this){}
        synchronized (this){
    
    
            if (ticketCount > 0){
    
    
                System.out.println(Thread.currentThread().getName()+"买了第"+ticketCount+"张票");
                --ticketCount;
            }else {
    
    
                System.out.println("票卖完了");
            }
            try {
    
    
                Thread.sleep(50);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }
    }
}

线程类:

public class TicketThread extends Thread{
    
    

    private SaleTicket saleTicket;

    public TicketThread(SaleTicket saleTicket) {
    
    
        this.saleTicket=saleTicket;
    }

    @Override
    public void run() {
    
    
        saleTicket.saleTicket();
    }
}

测试类:

public static void main(String[] args) {
    
    
    SaleTicket saleTicket = new SaleTicket();
    new TicketThread(saleTicket).start();
    new TicketThread(saleTicket).start();
}

1.2使用自定义内部对象实例:
售票类:

public class SaleTicket {
    
    
    private static int ticketCount=100;
    private Object obj=new Object();

    public void saleTicket(){
    
    
     while (ticketCount>0){
    
    
         // 锁对象,自定义对象
         synchronized (obj) {
    
    
             if (ticketCount > 0) {
    
    
                 System.out.println(Thread.currentThread().getName() + "买了第" + ticketCount + "张票");
                 --ticketCount;
             } else {
    
    
                 System.out.println("票卖完了");
             }
             try {
    
    
                 Thread.sleep(50);
             } catch (InterruptedException e) {
    
    
                 e.printStackTrace();
             }
         }
    }
    }
}

测试类与线程类同上
1.3普通方法上使用synchronized关键字(相当于是锁对象):
售票类:

public class SaleTicket {
    
    
    private static int ticketCount=100;

    public synchronized void saleTicket(){
    
    
     while (ticketCount > 0){
    
    
         if (ticketCount > 0){
    
    
             System.out.println(Thread.currentThread().getName()+"买了第"+ticketCount+"张票");
             --ticketCount;
         }else {
    
    
             System.out.println("票卖完了");
         }
         try {
    
    
             Thread.sleep(100);
         } catch (InterruptedException e) {
    
    
             e.printStackTrace();
         }
    }
    }
}

测试类与线程类同上
1.使用synchroized锁类:
2.1使用synchroized(类名.class)锁类:

public class SaleTicket {
    
    
    private static int ticketCount=100;
    public void saleTicket(){
    
    
     while (ticketCount>0){
    
    
         synchronized (SaleTicket.class){
    
    
            if (ticketCount > 0){
    
    
                System.out.println(Thread.currentThread().getName()+"买了第"+ticketCount+"张票");
                --ticketCount;
            }else {
    
    
                System.out.println("票卖完了");
            }
            try {
    
    
                Thread.sleep(50);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }
    }
}

线程类和测试类同上
2.2静态方法上使用synchronized关键字(相当于是锁类):
售票类:

public class SaleTicket {
    
    
    private static int ticketCount=100;

    public static synchronized void saleTicket(){
    
    
     while (ticketCount > 0){
    
    
         if (ticketCount > 0){
    
    
             System.out.println(Thread.currentThread().getName()+"买了第"+ticketCount+"张票");
             --ticketCount;
         }else {
    
    
             System.out.println("票卖完了");
         }
         try {
    
    
             Thread.sleep(100);
         } catch (InterruptedException e) {
    
    
             e.printStackTrace();
         }
    }
    }
}

线程类:

public class TicketThread extends Thread{
    
    

    private static int ticketCount=100;

    @Override
    public void run() {
    
    
        //saleTicket.saleTicket();
        SaleTicket.saleTicket();
    }

}

测试类:

public static void main(String[] args) {
    
    
    new TicketThread().start();
    new TicketThread().start();
}

   关于使用synchronized关键字之后本地模拟出现多线程中只有一个线程完成所有任务的情况,一般是和CPU有关,本场景中可以增到票数.
   如有描述不当之处,还望指正,期待发现问题,解决问题!

猜你喜欢

转载自blog.csdn.net/weixin_43401380/article/details/115282803
今日推荐