亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区
Chinaunix
標(biāo)題:
關(guān)于Java 線程的一個問題
[打印本頁]
作者:
newcih
時間:
2016-07-16 08:37
標(biāo)題:
關(guān)于Java 線程的一個問題
前幾天,在敲到一個代碼,碰到如下情況:
@Override
public void run()
{
while(true)
{
// 注釋句在此 System.out.println(flag);
if (flag)
{
System.out.println("flag is true");
// 當(dāng)標(biāo)識位為true時,執(zhí)行到這里,轉(zhuǎn)為false
flag = false;
}
}
}
復(fù)制代碼
情況是,我在外部改變flag的值,每隔0.5秒就在外部將flag設(shè)置為true。結(jié)果這段代碼中注釋句去掉注釋的話,會有"flag is true"的輸出,但是注釋加上的話,就永遠(yuǎn)不會輸出"flag is true"
有誰可以給出個合理解釋嗎?
全部代碼如下:
class MyThread extends Thread
{
// 設(shè)置標(biāo)識位
private boolean flag = false;
public void setFlag()
{
flag = true;
}
// 線程執(zhí)行
@Override
public void run()
{
while(true)
{
// System.out.println(flag);
if (flag)
{
System.out.println("flag is true");
// 當(dāng)標(biāo)識位為true時,執(zhí)行到這里,轉(zhuǎn)為false
flag = false;
}
}
}
public static void main(String[] args)
{
MyThread t = new MyThread();
t.start();
// 每隔0.5秒設(shè)置標(biāo)識位為true
while (true)
{
try{
Thread.sleep(500);
} catch (InterruptedException e)
{}
t.setFlag();
}
}
}
復(fù)制代碼
作者:
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;
}
// 線程執(zhí)行
@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();
}
}
}
復(fù)制代碼
作者:
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;
}
// 線程執(zhí)行
@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();
}
}
}
復(fù)制代碼
作者:
arch_yzs
時間:
2016-11-27 16:14
上面的代碼 是不具備線程安全性的. "結(jié)果這段代碼中注釋句去掉注釋的話,會有"flag is true"的輸出,但是注釋加上的話,就永遠(yuǎn)不會輸出"flag is true" "
你看到的這個輸出結(jié)果是不可控的, 這里一共有兩個線程 : 1 main方法, 2 t.start()
兩個線程可以同時操作 對象t的 flag屬性, 有可能main方法剛剛調(diào)用完 t.setFlag()方法 第二個線程就執(zhí)行了 flag = false , 而main方法中的第二次循環(huán)還沒有來得及第二次調(diào)用setFlag()方法 . t.start()線程的第二次循環(huán)就已經(jīng)執(zhí)行到了if(flag),而此時 flag = false. 所以不輸出 flag is true. (跟你睡眠0.5秒與否關(guān)系不大,只是不睡眠,打印flag is true的可能性會比較大)
輸出結(jié)果會受 兩個線程的執(zhí)行進度影響, 而我們幾乎無法控制這兩個線程的執(zhí)行進度,即使你對線程設(shè)定了執(zhí)行優(yōu)先級. 所以最后的輸出結(jié)果是完全不可預(yù)期的,你看到的結(jié)果只是一個現(xiàn)象,可能同樣的代碼你放到不同的機器上結(jié)果又會不同.跟你的注釋句也沒什么關(guān)系. 至于你問為什么會看到這樣的輸出結(jié)果, 只能說 不可控 什么輸出結(jié)果都有可能.
所以最好使用synchronized來控制線程同步,保證某些代碼不會被 不同線程同時執(zhí)行, 比如這里 對flag值的操作
歡迎光臨 Chinaunix (http://www.72891.cn/)
Powered by Discuz! X3.2