多线程关于volatile关键字的问题

最近在学习多线程的问题,在学到volatile关键字的时候遇到了一个问题,请有缘人帮我解答...

上代码:

这是线程类;

package cn.whu.javaBasic.Thread.Test18;

public class Service {
    //volatile   //此处注释与否结果不一样,符合volatile关键字的用法
    private   boolean isRun;

    public Service(boolean isRun){
        this.isRun = isRun;
    }

    public void run(){

        while(isRun){
            //System.out.println("is running...");
        }
        System.out.println("stoped...");
    }

    public void stop(){
        isRun=false;
    }
}

class ThreadA extends Thread{
    private Service service;

    public ThreadA(Service service){
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.run();
    }
}

class ThreadB extends Thread{
    private Service service;

    public ThreadB(Service service){
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.stop();
    }
}

这是程序入口;

package cn.whu.javaBasic.Thread.Test18;

public class ThreadTest {
    public static void main(String[] args) throws InterruptedException {
        Service service = new Service(true);
        ThreadA threadA = new ThreadA(service);
        ThreadB threadB = new ThreadB(service);
        threadA.start();
        Thread.sleep(2000);
        threadB.start();
        System.out.println("has already stopped...");
    }
}

有两个地方需要注意一下:

1,isRun属性前加volatile关键字时,程序运行结果:

D:\software\develop\JDK\bin\java "...

//两秒后打印出来
has already stopped...
stoped...

Process finished with exit code 0

没加volatile关键字程序运行结果:

D:\software\develop\JDK\bin\java ...
has already stopped...

程序没有停下来。

这个地方的原理不懂的可以查一下volatile关键字作用,此处不详述。

2,Service类的run()方法的while循环中,

public void run(){

        while(isRun){
            //System.out.println("is running...");
        }
        System.out.println("stoped...");
    }

System.out.println(i);这段代码添加与否对程序运行结果有重大影响:

一下两种情况都未在isRun属性前加volatile关键字。

注释了的情况:

D:\software\develop\JDK\bin\java ...
has already stopped...

程序陷入死循环无法停止。

未注释的情况:

is running...
is running...
is running...
has already stopped...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
is running...
stoped...

Process finished with exit code 0

程序运行结束了。

这个结果实在想不通,有没有高人解答......

 

补充:

答案已经找到了:

synchronized关键字的特性:可以使多个线程访问同一资源具有同步性,而且它还具有将线程工作内存中的私有变量与公共内存中的变量同步的功能。

再看System.out.println();的源码:

public void println(String x){
   //对调用方法的对象加锁
    synchronized(this){
        print(x);
        newLine();
    }
}

对调用方法的对象加锁。由于synchronized关键字可以使多线程访问同一资源同步,所以该线程在调用这个方法时对 isRun变量的数据进行了更新。所以当线程B运行后改变了isRun的值,线程A能立马读取到更新后的值。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值