Chinaunix
标题:
关于Java 线程的一个问题
[打印本页]
作者:
newcih
时间:
2016-07-16 08:37
标题:
关于Java 线程的一个问题
前几天,在敲到一个代码,碰到如下情况:
@Override
public void run()
{
while(true)
{
// 注释句在此 System.out.println(flag);
if (flag)
{
System.out.println("flag is true");
// 当标识位为true时,执行到这里,转为false
flag = false;
}
}
}
复制代码
情况是,我在外部改变flag的值,每隔0.5秒就在外部将flag设置为true。结果这段代码中注释句去掉注释的话,会有"flag is true"的输出,但是注释加上的话,就永远不会输出"flag is true"
有谁可以给出个合理解释吗?
全部代码如下:
class MyThread extends Thread
{
// 设置标识位
private boolean flag = false;
public void setFlag()
{
flag = true;
}
// 线程执行
@Override
public void run()
{
while(true)
{
// System.out.println(flag);
if (flag)
{
System.out.println("flag is true");
// 当标识位为true时,执行到这里,转为false
flag = false;
}
}
}
public static void main(String[] args)
{
MyThread t = new MyThread();
t.start();
// 每隔0.5秒设置标识位为true
while (true)
{
try{
Thread.sleep(500);
} catch (InterruptedException e)
{}
t.setFlag();
}
}
}
复制代码
作者:
jeppeter
时间:
2016-07-18 12:38
本帖最后由 jeppeter 于 2016-07-18 12:42 编辑
我只修改了一个地方就可以使你的代码运行成功了。
public class MyThread extends Thread {
[color=Red]private volatile boolean flag = false;[/color]
public void setFlag() {
flag = true;
}
// 线程执行
@Override
public void run() {
while (true) {
if (flag) {
System.out.println("flag is true");
flag = false;
}
}
}
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e)
{}
t.setFlag();
}
}
}
复制代码
作者:
jeppeter
时间:
2016-07-18 12:41
本帖最后由 jeppeter 于 2016-07-18 12:43 编辑
我只修改了一个地方就可以使你的代码运行成功了,就是flag添加了volatile属性。
public class MyThread extends Thread {
private volatile boolean flag = false;
public void setFlag() {
flag = true;
}
// 线程执行
@Override
public void run() {
while (true) {
if (flag) {
System.out.println("flag is true");
flag = false;
}
}
}
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e)
{}
t.setFlag();
}
}
}
复制代码
作者:
arch_yzs
时间:
2016-11-27 16:14
上面的代码 是不具备线程安全性的. "结果这段代码中注释句去掉注释的话,会有"flag is true"的输出,但是注释加上的话,就永远不会输出"flag is true" "
你看到的这个输出结果是不可控的, 这里一共有两个线程 : 1 main方法, 2 t.start()
两个线程可以同时操作 对象t的 flag属性, 有可能main方法刚刚调用完 t.setFlag()方法 第二个线程就执行了 flag = false , 而main方法中的第二次循环还没有来得及第二次调用setFlag()方法 . t.start()线程的第二次循环就已经执行到了if(flag),而此时 flag = false. 所以不输出 flag is true. (跟你睡眠0.5秒与否关系不大,只是不睡眠,打印flag is true的可能性会比较大)
输出结果会受 两个线程的执行进度影响, 而我们几乎无法控制这两个线程的执行进度,即使你对线程设定了执行优先级. 所以最后的输出结果是完全不可预期的,你看到的结果只是一个现象,可能同样的代码你放到不同的机器上结果又会不同.跟你的注释句也没什么关系. 至于你问为什么会看到这样的输出结果, 只能说 不可控 什么输出结果都有可能.
所以最好使用synchronized来控制线程同步,保证某些代码不会被 不同线程同时执行, 比如这里 对flag值的操作
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2