解决线程安全问题的方法

解决线程安全问题的方法一sychronized

package Text2;
public class RunnableImpl1 implements Runnable{
          
   
    //定义一个多线程共享的票源
    private int ticket=100;
    //创建一个锁对象
    Object obj=new Object();
    //设置线程任务:卖票
    @Override
    public void run() {
          
   
        //使用死循环,让卖票操作重复执行
        while(true){
          
   
            //同步代码块
            synchronized (obj){
          
   
                //先判断票是否存在
                if(ticket>0){
          
   
                    //提高安全问题出现的概率,让程序睡眠
                    try {
          
   
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
          
   
                        e.printStackTrace();
                    }
                    //票存在,卖票
                    System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket);
                    ticket--;
                }
            }

        }
    }
}
package Text2;
//模拟买票案例,创建3个线程,同时开启,对共享的票进行出售
public class demo5Ticket {
          
   
    public static void main(String[] args) {
          
   
        //创建Runnable接口的实现类对象
       RunnableImpl1 run=new RunnableImpl1();
       //创建Thread类对象,构造方法中传递Runnable接口的实现类对象
       Thread t1=new Thread(run);
        Thread t2=new Thread(run);
        Thread t3=new Thread(run);
        //调用start方法开启多线程
       t1.start();
       t2.start();
       t3.start();
    }
}

解决线程安全问题的方法二同步方法

package Text2;
public class RunnableImpl1 implements Runnable{
          
   
    //定义一个多线程共享的票源
    private int ticket=100;
    //创建一个锁对象
    Object obj=new Object();
    //设置线程任务:卖票
    @Override
    public void run() {
          
   
        //使用死循环,让卖票操作重复执行
        while(true){
          
   
          payTicket();
        }
    }
    public synchronized void payTicket(){
          
   
        //先判断票是否存在
        if(ticket>0){
          
   
            //提高安全问题出现的概率,让程序睡眠
            try {
          
   
                Thread.sleep(10);
            } catch (InterruptedException e) {
          
   
                e.printStackTrace();
            }
            //票存在,卖票
            System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket);
            ticket--;
        }
    }
}

解决线程安全问题的方法三Lock锁

package Text2;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class RunnableImpl1 implements Runnable{
          
   
    //定义一个多线程共享的票源
    private int ticket=100;
    //创建一个锁对象
    Object obj=new Object();
    Lock l=new ReentrantLock();
    //设置线程任务:卖票
    @Override
    public void run() {
          
   
        //使用死循环,让卖票操作重复执行
        while(true){
          
   
            //在可能会出现安全问题的代码前调用Lock接口中的lock方法获取锁
            l.lock();
            //先判断票是否存在
            if(ticket>0){
          
   
                //提高安全问题出现的概率,让程序睡眠
                try {
          
   
                    Thread.sleep(10);
                } catch (InterruptedException e) {
          
   
                    e.printStackTrace();
                }
                //票存在,卖票
                System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket);
                ticket--;
            }
            //在可能会出现安全问题的代码后调用Lock接口中的unlock方法释放锁
            l.unlock();
        }
    }

}

用finally可提高程序效率

经验分享 程序员 微信小程序 职场和发展