JAVA-线程安全和同步锁

线程安全

  • 概念:多个线程访问同一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他操作,调用这个对象的行为都可以获得正确的结果,那么这个对象就是线程安全的。
  • 多个线程对全局变量、静态变量只有读操作的话,这个全局变量、静态变量一般来讲是线程安全的,如果有写操作而未考虑线程同步,就可能产生线程安全问题。

一个简单的例子,多个卖票窗口卖同一堆票:

public class Sell_ticket implements Runnable{
    //有十张票
    int ticket_num = 10;
    @Override
    public void run() {
        while(true){
            if(ticket_num>0){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"售出"+ticket_num);
                ticket_num -= 1;
            }
        }
    }
}
public class Main {
    public static void main(String[] args) {
        Sell_ticket st = new Sell_ticket();
        Thread t0 = new Thread(st, "一号窗口");
        Thread t1 = new Thread(st, "二号窗口");
        Thread t2 = new Thread(st, "三号窗口");
        t0.start();
        t1.start();
        t2.start();
    }
}

一次运行结果如下:

三号窗口售出10
一号窗口售出10
二号窗口售出10
二号窗口售出7
一号窗口售出7
三号窗口售出7
一号窗口售出4
三号窗口售出4
二号窗口售出4
二号窗口售出1
三号窗口售出1
一号窗口售出-1

由上看出,几个线程间的票数不同步,这就是一种线程不安全。

线程同步

JAVA里的线程同步方法

同步锁Lock接口

某个线程在修改某个变量时,对其加上一个锁,这时其他线程就不能再对这个变量进行修改了,修改完成后再解锁。。
所在包:java.util.concurrent.locks.Lock
常用方法:

  • public void lock() :加同步锁
  • public void unlock() :释放同步锁

这里简单使用ReentrantLock(实现Lock接口的类)修改上述代码:

public class Sell_ticket implements Runnable{
    //有十张票
    int ticket_num = 10;
    //创建同步锁
    Lock lock = new ReentrantLock();
    @Override
    public void run() {
        while(true){
            //上锁
            lock.lock();
            if(ticket_num>0){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"售出"+ticket_num);
                ticket_num -= 1;
            }
            //解锁
            lock.unlock();
        }
    }
}

按照上述主函数运行之后的一次结果:

一号窗口售出10
二号窗口售出9
二号窗口售出8
三号窗口售出7
一号窗口售出6
一号窗口售出5
一号窗口售出4
二号窗口售出3
二号窗口售出2
二号窗口售出1

ok,问题解决。
关于Lock接口的使用方法还有很多,可以去看看API文档或者上网查(我分享的api文档)。以后用到更深入了回来填坑。

其他方法

留个坑…

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值