JAVA基础-线程安全

线程安全

线程安全问题通常发生于多线程操作中。

线程不安全的原因

  1. 线程执行方式:线程间是抢占式执行的,谁先抢到谁就执行,用户是不能干预的

  1. 操作不是原子性的:线程的自增操作主要是读取数据,加1,放回内存,在线程1修改的过程中其他线程都是可以读取数据进行操作的。

  1. 当多个线程操作同一个变量时,由于读取修改时间不同,读到的也许是其他线程未修改完的数据。

比如当线程1做自增操作,修改后还没放回内存时,线程2也来读取数据,也做了自增操作,但结果是线程1和2一共做了两次自增操作,而num只增了一次,试想一下,如果在我们所写的程序中,我们本希望两个线程可以互不干扰的操作一个变量,但最后却因为线程的同时操作导致结果不是预期的那样,就像下面的程序:

写三个线程,让这三个线程都对num做1000次自增,预期结果:num=3000

ThreadA
public class ThreadA extends Thread{
    public void run() {
        for(int i=0;i<1000;i++) {
            Manage.num++;
        }
    }
}
ThreadB
public class ThreadB extends Thread{
    public void run() {
        for(int i=0;i<1000;i++) {
            Manage.num++;
        }
    }
}
ThreadC
public class ThreadC extends Thread{
    public void run() {
        for(int i=0;i<1000;i++) {
            Manage.num++;
        }
    }
}
启动线程
public class Manage {
    public static int num=0;
    static Object object=new Object();
    public static void main(String[] args) {
        ThreadA threadA=new ThreadA();
        ThreadB threadB=new ThreadB();
        ThreadC threadC=new ThreadC();
        threadC.start();
        threadB.start();
        threadA.start();
        try {
            threadA.join();//等待线程执行完成
            threadB.join();
            threadC.join();
        }catch(InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(num);
    }
}
运行结果

可以看到四次运行结果,只有最后一次达到预期,那么如何解决线程不安全的问题呢?

synchronized 关键字

想要保证线程自增过程中,其他线程不能修改,就要给修改变量的线程上锁,因为锁具有互斥性,同线程只有一个获取到锁,其他线程如果要获取就会发生阻塞,等线程结束释放锁,其他线程才可以竞争锁。

关键字的使用方法:
  1. 加到普通方法之前,将整个方法上锁

  1. 加到静态方法前,将类的类对象上锁

  1. 加到代码块前,将某个对象上锁

下面给三个线程num上锁:

    public void run() {
        for(int i=0;i<1000;i++) {
          synchronized (Manage.object) {
              Manage.num++;
            }
        }
    }

运行结果

运行多次结果都是3000

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值