Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在创建JFrame之前打开MIDI Synth会导致JVM挂起_Java_Swing_Jframe_Deadlock_Javax.sound.midi - Fatal编程技术网

Java 在创建JFrame之前打开MIDI Synth会导致JVM挂起

Java 在创建JFrame之前打开MIDI Synth会导致JVM挂起,java,swing,jframe,deadlock,javax.sound.midi,Java,Swing,Jframe,Deadlock,Javax.sound.midi,在使用Swing接口向MIDI编写程序时,我遇到了挂起,因此需要使用kill-9。以java MidiSwingProblem hang0 import java.lang.reflect.InvocationTargetException; import javax.sound.midi.MidiSystem; import javax.sound.midi.MidiUnavailableException; import javax.sound.midi.Synthesizer; impor

在使用Swing接口向MIDI编写程序时,我遇到了挂起,因此需要使用
kill-9
。以
java MidiSwingProblem hang0

import java.lang.reflect.InvocationTargetException;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Synthesizer;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class MidiSwingProblem {
    /**
     * JFrame never appears.  Hangs such that `kill -9` is required.
     */
    public static void hang0() throws MidiUnavailableException {
        Synthesizer synth = MidiSystem.getSynthesizer();
        synth.open();
        JFrame frame = new JFrame("MIDI Swing Hang 1");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    /**
     * JFrame never appears.  Hangs such that `kill -9` is required.
     */
    public static void hang1() throws MidiUnavailableException {
        Synthesizer synth = MidiSystem.getSynthesizer();
        synth.open();
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("MIDI Swing Hang 2");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }

    public static void solution0() throws MidiUnavailableException {
        // It doesn't matter whether .getSynthesizer() or new JFrame() is
        // called first.  It seems to work as long as synth.open() happens
        // after new JFrame().
        Synthesizer synth = MidiSystem.getSynthesizer();
        JFrame frame = new JFrame("MIDI Swing Solution 0?");
        synth.open();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public static void solution1() {
        new Thread() {
            public void run() {
                try {
                    Synthesizer synth = MidiSystem.getSynthesizer();
                    synth.open();
                } catch (MidiUnavailableException noMidi) {
                    noMidi.printStackTrace();
                }
            }
        }.start();

        JFrame frame = new JFrame("MIDI Swing Solution 1?");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public static void solution2() {
        new Thread() {
            public void run() {
                try {
                    Synthesizer synth = MidiSystem.getSynthesizer();
                    synth.open();
                } catch (MidiUnavailableException noMidi) {
                    noMidi.printStackTrace();
                }
            }
        }.start();

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("MIDI Swing Solution 2?");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }

    public static void main(String[] args) throws NoSuchMethodException
                                                , IllegalAccessException
                                                , InvocationTargetException {
        MidiSwingProblem.class.getMethod(args[0], new Class[0]).invoke(null);
    }
}
我假设
hang0()
中存在死锁,这是我的错,而不是J2SE中的错误。(我已经验证了Java1.7和OSX上的1.8的行为。)

我有三个问题:

  • 拿一个例子来说,我也试着把它写成
    hang1()
    ,但是没有用。为什么
    SwingUtilities.invokeLater()
    不够
  • 如果我在
    newjframe()
    之后重新排列行(请参见
    solution0()
    )以调用
    synth.open()
    ,那么它就工作了!为什么?
    solution0()
    是正确的,还是我只是运气好?对我来说,这似乎是一个站不住脚的解决办法
  • 为了更好地衡量,我还编写了
    solution1()
    solution2()
    ,这两个版本似乎都没有挂起。这些版本是否比
    solution0()
    更为正确,或者它们是否过于苛刻?将
    synth
    对象放在单独的线程中会使程序的其余部分很难使用它

  • 对于线程,不能保证哪个线程将首先运行

    因此,我建议您使用或编写代码,以确保正确初始化

    阅读更多

    示例代码:

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            try {
                Synthesizer synth = MidiSystem.getSynthesizer();
                synth.open();
            } catch (MidiUnavailableException e) {
                e.printStackTrace();
            }
    
            JFrame frame = new JFrame("MIDI Swing Solution 1?");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
    });
    

    你能解释一下吗?它似乎满足了在事件分派线程中初始化
    JFrame
    的要求。
    hang1()
    对我来说工作正常,但显示窗口需要时间。