2

この質問に答えている間、私はこの興味深い状況に出くわしました。

設計が不十分なこのコードを試してください-

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

class abc extends JFrame implements ActionListener
{

boolean button_clicked = false;
JButton b1;

abc(){
    this.setSize (400, 400);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.createUI();
}

void createUI(){
    this.setLayout(null);
    b1 = new JButton("Click here");
    b1.setSize(110,30);
    b1.setLocation(10,210);
    this.add(b1);
    b1.addActionListener(this);
}

public boolean isButton_clicked()
{
    return button_clicked;
}

public void setButton_clicked(boolean button_clicked) {
    this.button_clicked = button_clicked;
}



public void actionPerformed(ActionEvent arg0) {
    button_clicked = true;
}

}

これが主な方法です。

class tempMain extends JFrame
{

public static void main(String[] args) throws Exception
{
    abc temp = new abc();
    temp.setVisible(true);
    while(true)
    {
    //  Thread.sleep(200);
        if(temp.isButton_clicked())
        {
            JOptionPane.showMessageDialog(null, "Hello");
            temp.setButton_clicked(false);
        }
    }
}
}

これをWindows7マシンで実行したとき、ボタンをクリックしてから少なくとも約1分間は何も起こりませんでした(その後は待ちませんでした)。

さて、小さな変更を1つだけ行います-

  Thread.sleep(200); // uncomment this from the main.

そして驚くべきことに、それは機能し、JOptionPaneメッセージが表示されます。メッセージが最初に表示されないのはなぜですか?

4

1 に答える 1

2

そして驚くべきことに、それは機能し、JOptionPaneメッセージが表示されます。メッセージが最初に表示されないのはなぜですか?

button_clickedとしてマークされておらずvolatile、メインスレッドとは異なるスレッドから更新されています。コールバックはイベントハンドラスレッドから行われるため、。button_clickedとして定義されていない限り、メインスレッドは更新を認識しませんvolatile boolean。スリープ状態にすると、メモリバリアを越えて、button_clicked幸運にもメインスレッドで更新される可能性があります。

volatileについて、そして複数のスレッドを扱うときになぜそれが重要なのかについて、もう少し読んでください。


もう1つの問題は、にメッセージを吐き出す無限ループがあることですSystem.out。コンソールはクリックのチェックを停止するほど速く行を表示できないため、これはしばらくすると完全にブロックされます。

于 2012-08-29T17:57:34.860 に答える