首页 > 其他 > 详细

同步锁

时间:2019-11-02 15:34:25      阅读:70      评论:0      收藏:0      [点我收藏+]

问题代码:

public class Ticket implements Runnable {               //实现Runnable接口 创建多线程 引发 线程安全问题 
    
    private int tickets=100;
    
    public void run() {
        while(true) {                                          
            try {
                if(tickets>0) {    
                    
                Thread.sleep(10);                                //使线程休眠
            
                String name=Thread.currentThread().getName();   //获取当前线程的名称
                
                System.out.println(name+"正在发售第"+  tickets--  +"张票");  
                
               }else {
                  break;
               }
            } catch (InterruptedException e) {
                
                e.printStackTrace();
            }    
        }
    }
}

测试类

 

public static void main(String[] args) {  
        
        Ticket ticket= new Ticket();               //创建线程任务
        
        Thread t1 = new Thread(ticket,"窗口1");    // 定义4个线程对象,代表4个售票窗口
        Thread t2 = new Thread(ticket,"窗口2");
        Thread t3 = new Thread(ticket,"窗口3");
        Thread t4 = new Thread(ticket,"窗口4");
        
        t1.start();  //开启四个线程
        t2.start();
        t3.start();
        t4.start();
        
         
    }

 

 

结果:

   从运行结果看,不合逻辑    出现负数 ...

 

解决方式一: 使用同步代码块

public class Ticket implements Runnable {    //解决线程安全问题,使用 同步代码块(同步锁)
    private int tickets=100;
    public void run() {
        while(true) {   
            synchronized(this) {  //将this设置为 锁对象
            try {
                if(tickets>0) {     
                Thread.sleep(10);   //使线程休眠
            
                String name=Thread.currentThread().getName();   //获取当前线程的名称
                
                System.out.println(name+"正在发售第"+  tickets--  +"张票");  
               }else {
                  break;
               }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
      }
    }
}

测试代码:

public static void main(String[] args) {  
        
        Ticket ticket= new Ticket();//创建线程任务
        
        // 定义4个线程对象,代表4个售票窗口
        Thread t1 = new Thread(ticket,"窗口1");    
        Thread t2 = new Thread(ticket,"窗口2");
        Thread t3 = new Thread(ticket,"窗口3");
        Thread t4 = new Thread(ticket,"窗口4");
        
        //开启四个线程
        t1.start();  
        t2.start();
        t3.start();
        t4.start();
    }

 

问题得到解决:

 

方式二:使用同步方法

public class Ticket implements Runnable {    //解决线程安全问题  使用 同步方法             
    private int tickets=100;
    public void run() {
        while(true) {  
            saleTicket();     //调用售票方法
            if(tickets<=0) {
                break;
            }
        }
    }
    private synchronized void saleTicket() {   //定义一个同步方法  saleTicket() 
        if(tickets>0) {
        try {
            if(tickets>0) {     
            Thread.sleep(10);                                //使线程休眠10ms
            String name=Thread.currentThread().getName();   //获取当前线程的名称
            System.out.println(name+"正在发售第"+  tickets--  +"张票");  
           }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }    
     }
    }
}

 

 

测试类:

    public static void main(String[] args) {  
        Ticket ticket= new Ticket();               //创建线程任务
        Thread t1 = new Thread(ticket,"窗口1");    // 定义4个线程对象,代表4个售票窗口
        Thread t2 = new Thread(ticket,"窗口2");
        Thread t3 = new Thread(ticket,"窗口3");
        Thread t4 = new Thread(ticket,"窗口4");
        t1.start();  //开启四个线程
        t2.start();
        t3.start();
        t4.start();
    }

 

同步锁

原文:https://www.cnblogs.com/penguin1024/p/11781534.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!