2012-10-10 155 views
3

對於我來說,我無法弄清楚爲什麼這個程序在Java 7中不起作用。我已經在使用Java 6時沒有問題地運行它,但是隻要我用Java 7運行它, ,它不起作用。與Java不兼容7

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 

public class HelloWorld implements ActionListener { 

JButton button; 
boolean state; 

public HelloWorld(){ 
    init(); 
    state = false; 
    System.out.println("state - "+state); 

    while (true){ 
     if (state == true){ 
      System.out.println("Success"); 
     } 
    } 
} 

private void init(){ 
    JFrame frame = new JFrame(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    button = new JButton("Button"); 
    button.addActionListener(this); 
    frame.add(button); 
    frame.pack(); 
    frame.setVisible(true); 
} 

@Override 
public void actionPerformed(ActionEvent e) { 
    JButton source = (JButton)e.getSource(); 

    if (source == button){ 
     state = !state; 
     System.out.println("state - "+state); 
    } 
} 

/** 
* @param args the command line arguments 
*/ 
public static void main(String[] args) { 
    new HelloWorld(); 
} 

} 

使用Java 6,如果我按下按鈕,它會打印出那句「成功」,直到我再次按下按鈕。使用Java 7註冊該按鈕被按下並且狀態值已更改爲true,但從不打印短語「成功」。這是怎麼回事?

回答

4

volatile添加到字段聲明。

沒有volatile,字段中的更改不保證在其他線程上可見。
特別是,JITter可以自由地相信該字段永遠不會在主線程上發生變化,從而完全刪除if

+1

非常感謝!就是這樣。這是Java 7的一項新功能嗎?我不得不承認,我對Java的知識完全是自學的,所以我可以對許多事情無知,但我從未見過這個詞。 – user1630640

+0

@ user1630640:否;這可能是JITter的一個變化。如果你想做多線程開發,我推薦閱讀Java Concurrency in Practice。如果沒有,你應該堅持Swing工作者線程。多線程是_hard_。 – SLaks

0

當你展示的JFrame

frame.setVisible(true); 

Java的顯示窗口,並停止在該行的執行。

您配置窗口關閉退出上:您關閉窗口後

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

該程序將終止。

因此,調用init()之後的代碼將永遠不會執行。

+0

他已經在'init()'中做了這個。另外,'setVisible()'將_never_停止執行。該行只是防止主線程停止時JVM終止。他實際上並不需要它。 – SLaks

+0

如果我關閉了窗戶,情況會如此,但我不必這樣做。在初始化框架並添加了按鈕(在init()方法中發生)後,接下來要處理的是while循環(只要我不關閉窗口)。基本上,當JFrame打開時,while循環會永久運行。我的問題是if語句在while循環中不起作用。 – user1630640