您的位置:首页 > 其它

关于线程volatile关键字

2017-05-26 11:24 197 查看

volatile关键字

1.示例介绍。

public class TestVolite {
public static void main(String[] args) {
ThreadDemo demo = new ThreadDemo();
new Thread(demo).start();
while (true) {
if (demo.isFlag()) {
System.out.println("---------------");
break;
}
}
}
}

class ThreadDemo implements Runnable {
private boolean flag = false;

public boolean isFlag() {
return flag;
}

public void setFlag(boolean flag) {
this.flag = flag;
}

@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = true;
System.out.println("flag = " + isFlag());
}
}
//执行结果
//flag = true


上面的案例并没有输出

- - - - - - - -

原因:

两个线程访问一个数据,一个线程改变数据时,另一个线程并没有改变。

这里涉及到内存可见性:

当程序运行jvm会为每一线线程分配一个独立的缓存提高效率,首先,在主存中存着flag,启动两个线程,一个是读取,一个是写,线程一将flag进行修改时会将把flag读到线程一的缓存中,将flag修改之后将数据写入主存,此时main线程执行,将主存的flag读取到缓存中flag为false,当main线程读取完之后,线程一打印flag,main线程执行while非常速度快,main线程没有机会从主存中获取flag的值。

就是因为多个线程在访问共享数据数据时,彼此不可见。

使用同步锁synchronized()解决但是同步锁会使效率低,会阻塞挂起,等待cpu下一次分配时间。

使用volatile 当多个线程进行数据共享时,内存中的数据是可见的。(及时刷新缓存数据-可以理解为在主存中操作)

使用volatile 降低效率,不能重排序(jvm底层).

使用volatile关键字

public class TestVolite {
public static void main(String[] args) {
ThreadDemo demo = new ThreadDemo();
new Thread(demo).start();
while (true) {
if (demo.isFlag()) {
System.out.println("---------------");
break;
}
}
}
}

class ThreadDemo implements Runnable {
private volatile boolean flag = false;

public boolean isFlag() {
return flag;
}

public void setFlag(boolean flag) {
this.flag = flag;
}

@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = true;
System.out.println("flag = " + isFlag());
}
}
//执行结果
//---------------
//flag = true


volite 1.没有互斥性,2.不能保证变量的原子性
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Volatile