Java多线程学习-线程安全

解决java多线程中线程安全的三种方式

1.什么是线程安全

 private int count = 100;
    @Override
    public void run() {
    	while(true){
	 		if(count>0){
	             System.out.println(Thread.currentThread().getName()+"卖出第"+count+"张票");
	             count--;
	         }
		}
           
    }

上述代码中,假设3个线程ABC同时访问count变量,假设A在打印后失去了CPU的拥有权,此时count并未–,这时B拥有了cpu而此时count是100,这就造成了,他们同时卖出了第100张票,此时线程不安全

解决方式1利用同步锁(同步代码块)

while(true){
	synchronized (obj){
            if(count>0){
                System.out.println(Thread.currentThread().getName()+"卖出第"+count+"张票");
                count--;
            }
        }
}

利用synchronized (锁对象){}格式将线程不安全代码包裹,这时当线程到达时会先获取锁对象,执行完会释放锁对象,在运行过程中其他线程到达时拿不到锁对象,并不能执行代码,注意锁对象可以是任意对象

解决方式2利用同步方法

public void run() {
        while(true) {
            this.sale();
        }
    }
    private synchronized void sale(){
        if (count > 0) {
            System.out.println(Thread.currentThread().getName() + "卖出第" + count + "张票");
            count--;
        }
    }

同步方法是利用在方法声明时加上synchronized 关键字即可,内部也是利用锁对象来确定访问权限的,而这里的锁对象是this,注意:若方法是静态的则锁对象是该类的字节码

解决方式3利用Lock方式(推荐*)

lock是一个接口,主要是使用它的实现类
创建类ReentrantLock在不安全代码块之前上锁,在代码结束时释放锁,这种做法的好处,可以在try前上锁,在finally解锁,出现异常亦可以很方便的解锁

private int count = 1000;
    Lock lock = new ReentrantLock();
    @Override
    public void run() {
        while(true) {
            lock.lock();
                if (count > 0) {
                    System.out.println(Thread.currentThread().getName() + "卖出第" + count + "张票");
                    count--;
                }
            lock.unlock();
        }

    }
发布了47 篇原创文章 · 获赞 6 · 访问量 2222

猜你喜欢

转载自blog.csdn.net/weixin_44467251/article/details/101061818