IllegalThreadStateException一次又一次发生.停止后需要重新启动线程



需要制作一个音乐播放器作为我的简单Java项目。它打开一个文件并在文本字段中加载名称。当play被按下时,名称在文本框中被包围,当pause被按下时,包围被暂停。播放暂停是JTogglebuttons和我有一个按钮名称停止。使用多线程,我可以播放和暂停字符串,但在我按下停止一次…如果我再次打开一个新的音乐文件并按下播放,它会显示一个illegalthreadstate异常。请帮帮我……注:我还没有把代码播放音乐在它..一旦这个问题解决了,我就把它放进去。非常感谢你的回复

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import sun.audio.*;
public class search extends Thread implements ActionListener
{
JFrame f;
JButton stop,open;
JToggleButton play;
JTextField tf,text;
JTextArea ta;
JLabel lab,lab1;
String str,dest;
JScrollPane scrol;
File fl;
int myfl=0,myfl1=0,myfl2=0;
search()
{
    f=new JFrame("Music Player");
    f.setLayout(null);
    f.setSize(620,300);
    play=new JToggleButton("play");
    play.setBounds(100,150,270,30);
    play.addActionListener(this);
    f.add(play);
    play.setEnabled(false);

    stop=new JButton("stop");
    stop.setBounds(400,150,120,30);
    stop.addActionListener(this);
    f.add(stop);
    stop.setEnabled(false);
    open=new JButton("open");
    open.setBounds(100,200,420,30);
    open.addActionListener(this);
    f.add(open);    

    tf=new JTextField();
    tf.setBounds(25,50,565,40);
    tf.setFont(new Font("DK BabySitter",Font.BOLD,20));
    tf.setHorizontalAlignment(JTextField.CENTER);
    f.add(tf);
    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}
public void actionPerformed(ActionEvent ae)
{
   if(ae.getActionCommand().equals("open"))
    {
        FileDialog fd=new FileDialog(f,"Open Box",FileDialog.LOAD);
        fd.setSize(300,300);
        fd.setVisible(true);
    String s1="mp3";
    str=fd.getFile();
    dest=fd.getDirectory()+fd.getFile();
    if(str.toLowerCase().endsWith(s1))
    {
            tf.setText(str);
        //pause.setEnabled(true);
        play.setEnabled(true);
        stop.setEnabled(true);
    }
    else
    {
        JOptionPane.showMessageDialog(f, "Select a valid file format"); 
    }

    }
   if(ae.getActionCommand().equals("stop"))
    {   
    play.setLabel("play");
    myfl1=1;
        tf.setText(" "); 
    stop();
    }
   if(ae.getActionCommand().equals("play"))
    {   
    try
    {
        play.setLabel("pause");
        if(myfl==1 && myfl1==0)
        {
            resume();
        }
        if(myfl==0 || myfl1==1)
        {
            start();
        }
    }
    catch(IllegalThreadStateException e)
    {
        tf.setText("error a gya re");
        Thread newth= new Thread();
        newth.start();
    }
    }
   if(ae.getActionCommand().equals("pause"))
    {
    play.setLabel("play");
    myfl=1;
    suspend();
    }

} 
public void run()
{
    try
    {
        String rot=tf.getText();
    char rotn[]=new char[rot.length()];
    int flag=rot.length();
    int move=0;
    rotn=rot.toCharArray();
    tf.setText(" ");
    for(;;)
    {
        for(;;)
        {   
            sleep(100);
            tf.setText( tf.getText() + rotn[move]);
            move++;
            if(move==(flag-1))
            {   
                move=0;
                break;
            }
        }
    tf.setText(" ");    
    }
    }

    catch(Exception e)
    {
        tf.setText("error occured");
    }                 
}
    public static void main(String args[])
    {
      try {
            // Set System L&F
        UIManager.setLookAndFeel(
            UIManager.getSystemLookAndFeelClassName());
    } 
    catch (UnsupportedLookAndFeelException e) {
       // handle exception
    }
    catch (ClassNotFoundException e) {
       // handle exception
    }
    catch (InstantiationException e) {
       // handle exception
    }
    catch (IllegalAccessException e) {
       // handle exception
    }
        new search();
    }
}

不能使用Thread.stop(), Thread.suspend()Thread.resume()。这些方法已被弃用,并被明确地记录为具有严重的含义(如潜在的死锁等)。参见为什么是线程。停止,线程。suspend和Thread。弃用?恢复。

在此特定情况下,出现异常是因为您不能多次start()Thread。你需要编码你的线程(或者更好:不扩展Thread,但实现Runnable),这样它就可以正确地处理应用程序的暂停,启动,停止等,而不用使用Thread的过时和危险的方法。

出现此错误的原因是您试图手动操作正在运行的线程的状态。

你在这里使用的方法都是不推荐的- stop, resume, suspend -这些都应该避免。

一个更好的方式来考虑你的程序是如何运行的是一个线程是活的或不是。它可能不会在实际的run方法中做任何事情,但是在任何时候你都不会暂停/挂起/停止实际的线程-你只是暂停/停止应用程序逻辑。

一个非常快速的解决方法是将所有的stop/suspend/resume替换为以下命令:

private volatile boolean paused = false;
private void pausePlayer(boolean pause) {
    this.paused = pause;
}
then everywhere you need to pause the player use:
pausePlayer(true);
and when you want to resume it use:
pausePlayer(false);

在run方法中将第二个for循环替换为:

for (; ; ) {
    while(!paused) {
        // do your work

请注意,尽管我认为这个程序存在更大的结构问题——将普通线程与Swing混合可能会有问题。我建议你研究一下使用SwingWorker,因为它是为你想要做的事情而明确设计的。

最新更新