线程不安全的三种解决方法

线程不安全

原因:

  • 多个线程去争抢一个数据,导致某个阶段会出现一个数据被多个线程更改,从而出现错误。

解决方法:

  • synchronized(锁对象){要锁住的代码块}

注意,要看同一把锁,不能每个线程都生成自己的锁对象,要多个线程拥有一个所对象。

  • synchronized 要锁的方法
    格式大体上如图所示:
    在这里插入图片描述
  • 显示锁 Lock 子类 ReentrantLock
    在这里插入图片描述
    公平锁:先来先到,排队

非公平锁:谁先抢到就是谁的

三种方法的例子:

  • synchronized(锁对象){要锁住的代码块}
     /**
     * 线程同步:synchronized
     * @param args
     */
    public static void main(String[] args) {

        //线程不安全
        //解决方案一:同步代码块
        //格式:synchronized(锁对象){这里面是同步的代码块}
        Runnable run =new Ticket();
        new Thread(run).start();
        new Thread(run).start();
        new Thread(run).start();

    }
    static class Ticket implements Runnable{

        //票数
        private int count =10;
        private Object o =new Object(); //这里的o就是锁
        @Override
        public void run() {
//             Object o =new Object();
                while (true) {
                    synchronized (o) {
                        if (count > 0) {
                            System.out.println("正在准备卖票");
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            count--;
                            System.out.println(Thread.currentThread().getName()+"出票成功,剩余票数:" + count);
                        } else {
                            break;
                        }
                    }
            }
        }
    }
  • 锁方法
/**
     * 线程同步:synchronized
     * @param args
     */
    public static void main(String[] args) {

        //线程不安全
        //解决方案二:同步方法
        //格式:synchronized(锁对象){这里面是同步的代码块}
        Runnable run =new Ticket();
        new Thread(run).start();
        new Thread(run).start();
        new Thread(run).start();

    }
    static class Ticket implements Runnable{

        //票数
        private int count =10;
        @Override
        public void run() {
            while (true) {
                    boolean flag = sale();
                    if(!flag){
                        break;
                    }
            }
        }
        public synchronized boolean sale(){
            if (count > 0) {
                System.out.println("正在准备卖票");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count--;
                System.out.println(Thread.currentThread().getName()+"出票成功,剩余票数:" + count);
                return true;
            }
            return false;
        }
    }
  • 显示锁
 /**
     * 线程同步:synchronized
     * @param args
     */
    public static void main(String[] args) {

        //线程不安全
        //解决方案三:显示锁  Lock 子类 ReentrantLock
        //
        Runnable run =new Ticket();
        new Thread(run).start();
        new Thread(run).start();
        new Thread(run).start();

    }
    static class Ticket implements Runnable{

        //票数
        private int count =10;
        //显示锁 l  fail参数为true就是公平锁,false就是非公平锁
        private Lock l = new ReentrantLock();
        @Override
        public void run() {
            while (true) {
                l.lock();
                if (count > 0) {
                    System.out.println("正在准备卖票");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    count--;
                    System.out.println(Thread.currentThread().getName()+"出票成功,剩余票数:" + count);
                }else {
                    break;
                }
                l.unlock();
            }
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值