JAVA 实例变量和线程安全

线程类中的实例变量针对其他线程可以有共享和不共享之分。下面通过两个简单的例子来说明!

1、不共享数据的情况

public class MyThread extends Thread{
    private int count = 5;

public MyThread(String name){
    super();
    this.setName(name);
}

@Override
    public void run(){
    super.run();
    while (count > 0)
    {
        count--;
        System.out.println("由 " + MyThread.currentThread().getName() + " 计算,count=" + count);
    }
}

public static void main(String[] args){
    MyThread a = new MyThread("A");
    MyThread b = new MyThread("B");
    MyThread c = new MyThread("C");
    a.start();
    b.start();
    c.start();
}
}

运行结果:
在这里插入图片描述
可以看出每个线程都有一个属于自己的实例变量count,它们之间互不影响。我们再来看看另一种情况。

2、共享数据的情况

public class SharedVariableThread extends Thread{
    private int count = 5;

@Override
    public void run(){
    super.run();
    count--;
    System.out.println("由 " + SharedVariableThread.currentThread().getName() + " 计算,count=" + count);
}

public static void main(String[] args){
    SharedVariableThread mythread = new SharedVariableThread();
    // 下列线程都是通过mythread对象创建的
    Thread a = new Thread(mythread, "A");
    Thread b = new Thread(mythread, "B");
    Thread c = new Thread(mythread, "C");
    Thread d = new Thread(mythread, "D");
    Thread e = new Thread(mythread, "E");
    a.start();
    b.start();
    c.start();
    d.start();
    e.start();
}
}

运行结果:
在这里插入图片描述
可以看出这里已经出现了错误,我们想要的是依次递减的结果。为什么呢??
因为在大多数jvm中,count–的操作分为如下下三步:
1、取得原有count值
2、计算i -1
3、对i进行赋值
所以多个线程同时访问时出现问题就是难以避免的了。

那么有没有什么解决办法呢?
答案是:当然有,而且很简单。给大家提供两种解决办法:一种是利用 synchronized 关键字(保证任意时刻只能有一个线程执行该方法),一种是利用 AtomicInteger 类(JUC 中的 Atomic 原子类)。大家如果之前没有接触 Java 多线程的话,可能对这两个概念不太熟悉,不过不要担心我后面会一一向你介绍到!这里不能用 volatile 关键字,因为 volatile 关键字不能保证复合操作的原子性。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值