Java volatile关键词问题

骆驼绵羊 2016-04-13 10:41:05


public class Test {

private int i = 0;
private Object object = new Object();
volatile static boolean flag=true;

public static void main(String[] args) {

Test test = new Test();
Thread thread1 = test.new MyThread("Thread-1");
Thread thread2 = test.new MyThread("Thread-2");

thread1.start();
thread2.start();
}


class MyThread extends Thread {

MyThread(String name) {
super(name);
}

@Override
public void run() {
while (flag) {

synchronized (object) {

i++;
System.out.println("i:" + i);
System.out.println("线程" + Thread.currentThread().getName() + "进入睡眠状态");

try {
Thread.currentThread();

Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getName() + "睡眠结束");

i++;
System.out.println("i:" + i);
flag = false;
}

}
}
}
}



这个运行结果是:
i:1
线程Thread-1进入睡眠状态
线程Thread-1睡眠结束
i:2
i:3
线程Thread-2进入睡眠状态
线程Thread-2睡眠结束
i:4

为什么Thread-2会运行呢
...全文
130 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
骆驼绵羊 2016-04-13
  • 打赏
  • 举报
回复
volatile不可以通知Thread-2 flag值已经变了么,还有如果把 flag =false 放到打印操作前Thread-2就不执行了,就这样吧

synchronized (object) {
                	
                	flag = false;
                    i++;                   
                    System.out.println("i:" + i);
                    
                    System.out.println("线程" + Thread.currentThread().getName() + "进入睡眠状态");
                    
                    try {
         .......
                    
                }       
结构就是这样了。 i:1 线程Thread-1进入睡眠状态 线程Thread-1睡眠结束 i:2
oh_Maxy 版主 2016-04-13
  • 打赏
  • 举报
回复
两个线程同时跑到while (flag) ,此时flag为true。 然后到synchronized (object),此时可能t1先抢到object了,t2等待。 t1处理完了,t2往下走。 所以t1、t2都走了一遍run方法的全流程。
oh_Maxy 版主 2016-04-13
  • 打赏
  • 举报
回复
两个线程同时执行的,同时到达那个判断,这个和volatile无关啊! 除非你把synchronized语句放到循环外边。
骆驼绵羊 2016-04-13
  • 打赏
  • 举报
回复
引用 4 楼 oh_Maxy 的回复:
两个线程同时执行的,同时到达那个判断,这个和volatile无关啊! 除非你把synchronized语句放到循环外边。
一语点破,懂了。。
oh_Maxy 版主 2016-04-13
  • 打赏
  • 举报
回复
这样,判断语句那段就变成串行了。
骆驼绵羊 2016-04-13
  • 打赏
  • 举报
回复
引用 1 楼 oh_Maxy 的回复:
两个线程同时跑到while (flag) ,此时flag为true。 然后到synchronized (object),此时可能t1先抢到object了,t2等待。 t1处理完了,t2往下走。 所以t1、t2都走了一遍run方法的全流程。
volatile不可以通知Thread-2 flag值已经变了么,还有如果把 flag =false 放到打印操作前Thread-2就不执行了,就这样


synchronized (object) {
                     
                    flag = false;
                    i++;                   
                    System.out.println("i:" + i);
                     
                    System.out.println("线程" + Thread.currentThread().getName() + "进入睡眠状态");
                     
                    try {
         .......
                     
                }   
结果就是这样了。 i:1 线程Thread-1进入睡眠状态 线程Thread-1睡眠结束 i:2

50,541

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧