java - 在 JVM7 中卡住,但在 JVM6 中不卡住

标签 java freeze

一位 friend 最近要求我制作一个简单的蜂鸣器程序,并在我为他编写的程序中发现了一个奇怪的“错误”。

如果按下某个键,蜂鸣器在几秒钟内快速复位,他会观察到在复位后第一次按下按键和“蜂鸣器”指示之间发生 2 到 3 秒的程序卡住。他安装了以下 Java:

build 1.7.0_25-b16

但是,通过以下 Java 安装,我在计算机上没有遇到此问题:

$ java -version
java version "1.6.0_51"
Java(TM) SE Runtime Environment (build 1.6.0_51-b11-457-10M4509)
Java HotSpot(TM) 64-Bit Server VM (build 20.51-b01-457, mixed mode)

解冻后,程序返回相应的键(即不是最后按下的键,而是重置后卡住前按下的第一个键)。这表明问题不在于听者,而在于对听者的 react 。

对于可能导致这种现象的原因有什么想法吗?预先感谢您的帮助。

源代码:

/**
 * Buzzer.java
 *
 * Buzzer
 */
package org.lexingtonma.lhs.nhb;

import java.awt.Color;
import java.awt.DefaultKeyboardFocusManager;
import java.awt.Font;
import java.awt.KeyEventDispatcher;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;


/**
 * @author Arman D. Bilge
 *
 */
public class Buzzer extends JFrame implements KeyListener {

    private static final long serialVersionUID = 7492374642744742658L;
    private static final String BUZZ_A = "BuzzA.wav";
    private static final String BUZZ_B = "BuzzB.wav";
    private Clip buzz = null;
    private boolean listening = true;
    private final JTextField display = new JTextField(3);
    private final JButton reset = new JButton("Reset");

    {

        DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager()
            .addKeyEventDispatcher(new KeyEventDispatcher() {
                public boolean dispatchKeyEvent(KeyEvent e) {
                    keyTyped(e);
                    return false;
                }
            });
        setTitle("Buzzer");
        final JPanel panel = new JPanel();
        setSize(256, 162);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        display.setFont(new Font("Helvetica", Font.BOLD, 64));
        display.setForeground(Color.WHITE);
        display.setVisible(true);
        display.setEditable(false);
        display.setHorizontalAlignment(JTextField.CENTER);
        panel.add(display);
        reset.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                display.setText("");
                display.setBackground(Color.WHITE);
                listening = true;
                reset.setEnabled(false);
            }
        });
        reset.setEnabled(false);
        panel.add(reset);
        add(panel);
        try {
            buzz = AudioSystem.getClip();
        } catch (LineUnavailableException e) {
            JOptionPane.showMessageDialog(this, e.getLocalizedMessage(), "FATAL ERROR", JOptionPane.ERROR_MESSAGE);
        }
    }

    public static final void main(String args[]) {
        Buzzer b = new Buzzer();
        b.setVisible(true);
    }

    public void keyPressed(KeyEvent e) {
        // Do nothing        
    }

    public void keyReleased(KeyEvent e) {
        // Do nothing        
    }

    public void keyTyped(KeyEvent e) {
        final char c = e.getKeyChar();
        if (listening && Character.isLetterOrDigit(c)) {
            buzz.close();
            listening = false;
            if (Character.isDigit(c)) {
                display.setBackground(Color.RED);
                try {
                    buzz.open(AudioSystem.getAudioInputStream(getClass().getResource(BUZZ_A)));
                    buzz.start();
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(this, ex.getLocalizedMessage(), "FATAL ERROR", JOptionPane.ERROR_MESSAGE);
                    System.exit(1);
                }
            } else {
                display.setBackground(Color.BLUE);
                try {
                    buzz.open(AudioSystem.getAudioInputStream(getClass().getResource(BUZZ_B)));
                    buzz.start();
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(this, ex.getLocalizedMessage(), "FATAL ERROR", JOptionPane.ERROR_MESSAGE);
                    System.exit(1);
                }
            }
            display.setText("" + c);
            reset.setEnabled(true);
        }

    }

}

jar :https://www.dropbox.com/s/62fl2i97m9hrx9m/Buzzer.jar

最佳答案

每次创建一个新的 Clip 对象并丢弃旧的会更安全。试试这个方法

public static void play(String name) {
   try{
     AudioInputStream sounds = AudioSystem.getAudioInputStream(Buzzer.class.getResource(name));
     final Clip clip = AudioSystem.getClip();
     clip.addLineListener(new LineListener() {
         public void update(LineEvent e) {
             LineEvent.Type type = e.getType();
             if(type == type.STOP) clip.close();
         }
     });
     clip.open(sounds);
     clip.start();
   } catch(Exception e){
       e.printStackTrace();
   }

}

关于java - 在 JVM7 中卡住,但在 JVM6 中不卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19204710/

相关文章:

swift - 进程运行时 Mac Cocoa 应用程序 GUI 卡住

Java 文件扫描器将光标移回

java - 在永久堆空间中处理许多符合 GC 条件的大型对象

java - 在 Eclipse 的 'VM arguments' 部分中设置 java.util.logging.config.file 属性时出现问题

c - 卡在打开串口

iOS 应用程序(挂起)在 iPhone 7 中卡住,但在模拟器中工作

java - 无法实例化 LinqMap 类型

java - Java中查找排除某些字符的字符串的第一部分的最佳方法

java - 每个测试用例设置的 WireMock 在第二次测试时挂起

c# - WebClient DownloadData 方法卡住 Form