Java多线程应用程序冻结

时间:2013-11-20 16:42:40

标签: java multithreading swing copy

如果我启动第二个线程,例如复制文件,为什么我的应用程序会冻结,直到该线程完成?我认为开始第二个线程就是解决这个问题的方法。

主要代码:

CopyFile Copy = new CopyFile();
Copy.start();
Copy.CopyFile("input.txt", "output.txt");

CopyFile.class

    public class CopyFile extends Thread 
    {
    public void CopyFile(File Input, File Output)
        {
            System.out.println("Copy file:" + Input.toString());
            System.out.println("Destination:" + Output.toString());

            InputStream InputReader = null;
            OutputStream OutputWriter = null;
            try 
            {
                InputReader = new FileInputStream(Input);
                OutputWriter = new FileOutputStream(Output);
                byte[] buffer = new byte[1024];
                int length;
                while ((length = InputReader.read(buffer)) > 0) 
                {
                    OutputWriter.write(buffer, 0, length);
                }
                InputReader.close();
                OutputWriter.close();
            }
            catch(FileNotFoundException e)
            {
                System.out.println("FileNotFoundException niggur");
            }
            catch(IOException e)
            {
                System.out.println("IOException niggur");
            }
        }
}

4 个答案:

答案 0 :(得分:1)

有点背景......

首先,这是一个最好的做法......不要扩展Thread实施Runnable。实际上,如果你看一下JVM Thread类,你会发现它实现了Runnable

在处理多个线程时,您需要将要运行的代码放在Runnable的{​​{1}}方法中的单独线程上。

在你的情况下,你启动线程,它有一个默认的空void run()方法 - 所以第二个线程什么都不做,然后终止。

随后,您调用void run()方法。然后在你的主线程上运行它,因此它会阻塞直到它完成。


您如何修复您的示例?

A)更改您的课程以实施CopyFile,它不应再延长Runnable

B)将输入/输出文件的参数放在类的构造函数

C)在单独的线程上运行Thread,将其传递给构造函数中的线程

Runnable

结果类看起来像这样:

Thread thread = new Thread(new CopyFile("A.txt", "B.txt");
thread.start();

进一步阅读?

每次想要在parellel中做一些工作时创建一个新线程是不好的做法,因为操作系统构造/销毁线程需要做很多工作。

相反,线程应该预先创建,他们应该订阅工作队列。

谷歌“生产者/消费者”模式,并通过教程。

如果这是针对您的应用程序的一次性操作,则可能不值得在ExecutorService中使用生产者/消费者模式,但如果您考虑在应用程序中广泛使用多线程,则应该阅读这些主题

答案 1 :(得分:0)

这有一个基本问题。扩展Thread类时,请确保将逻辑调用放在public void run()方法中。当调用它的start()方法时,它最终会调用run()方法。此run()方法继承自Runnable接口。

CopyFile copy = new CopyFile(in, out);
copy.start();

其中;

public class CopyFile extends Thread 
{

    private File input;
    private File output;

    public CopyFile(File Input, File Output) {
        this.input = input;
        this.output = output;
    } 

    public void run() {
        copy();
    }

    public void copy()
    {
        System.out.println("Copy file:" + input.toString());
        System.out.println("Destination:" + output.toString());

        // rest of the code as it is...
    }
}

答案 2 :(得分:0)

要让您的程序在另一个线程中运行,您必须覆盖run方法,其签名为public void run(),将您的代码放在那里,它将在一个单独的线程中运行。

答案 3 :(得分:0)

您需要覆盖Thread类的方法run并从方法run

调用方法copyFile

主要代码

CopyFile copy = new CopyFile(in, out);
copy.start();

类CopyFile

public class CopyFile extends Thread {
File in, out;
public CopyFile(File in, File out) {
  this.in = in;
  this.out = out;
}
public void run() {
  copyFile(in, out);
}
public void copyFile(File Input, File Output)
    {
        System.out.println("Copy file:" + Input.toString());
        System.out.println("Destination:" + Output.toString());

        InputStream InputReader = null;
        OutputStream OutputWriter = null;
        try 
        {
            InputReader = new FileInputStream(Input);
            OutputWriter = new FileOutputStream(Output);
            byte[] buffer = new byte[1024];
            int length;
            while ((length = InputReader.read(buffer)) > 0) 
            {
                OutputWriter.write(buffer, 0, length);
            }
            InputReader.close();
            OutputWriter.close();
        }
        catch(FileNotFoundException e)
        {
            System.out.println("FileNotFoundException niggur");
        }
        catch(IOException e)
        {
            System.out.println("IOException niggur");
        }
    }
}