我编写了相对大量的代码而没有考虑线程。我是Java的新手,也是一般的编程,所以我在搞清楚如何运行我在线程中构建的程序而不回到我的所有类并将它们更改为run()方法时遇到了一些麻烦。我甚至无法想象,如果我有多个方法可以与其他类分开调用,那是多么可能。
我似乎无法找到一种方法来为GUI中的代码(每次/每次)调用创建一个线程。假设我有一种将数据插入数据库的方法。该方法被命名和编写。我可以将该类和方法调用到我的main中,但是当我想调用其他方法时呢?我至少有25种以上的方法,而且我不能真正看到我的主要课程被超载25次作为“最佳实践”。有没有办法创建一个线程并给它一个动态处理的对象,所以说?
简而言之:我想在我的程序中使用线程而不会超载我的主程序,我该怎么办?
答案 0 :(得分:3)
老实说,没有将单线程应用程序转换为多线程应用程序的通用方法,因为它根据您的目标需要不同的设计。而“多线程应用程序”并不是真正的目标:)
您没有指定构建UI的方式。但是,如果您使用Swing并希望在不冻结用户界面的情况下执行一些冗长的任务,请使用SwingWorker
总的来说,我建议您阅读“Java Concurrency in Practice”一书。这很不错。
答案 1 :(得分:1)
您不需要在自己的线程中运行每个方法/类,也不需要实现run方法。你应该做的是,对于用户可以执行的每个动作,应该有一个实现Action(或类似的接口)的相应类。当用户在UI上调用操作时,您应该将操作添加到队列中。
然后,单独的线程池应该从队列中执行操作并执行它们(通过操作界面公开的方法)。
您需要确保每个操作都是线程安全的,并且能够与其他操作同时运行。这不是一项简单的任务,通常不是初学者能够做到的事情。
仅仅将渲染代码与处理代码分开就足够了(因此只有2个线程,用户一次只能运行一个动作)。
答案 2 :(得分:1)
没有必要让你的所有类都有一个run方法或实现Runnable通常你想在一个单独的线程中做一些特定的事情,通常这样你就不会在你执行像与数据库,文件系统或网络通信。
最简单的方法是在需要时创建一个新线程:
Thread t = new Thread() {
public void run() {
// do whatever work you want...
}
};
t.start();
答案 3 :(得分:0)
您可以创建一个匿名内部类,可以执行您需要的任何操作。考虑以下内容。创建了一个新的(未命名的)Runnable子类,它执行所需的实际步骤。
public class GuiCommandDelegator {
void performBackgroundSave(final Document document, final String filename) {
Runnable runnable = new Runnable() {
@Override void run() {
document.save (filename);
}
};
Thread thread = new Thread(runnable);
thread.run();
}
}
当然存在缺点,但是通过专门用于特定目的的类来填充线程管理代码会更糟。
答案 4 :(得分:0)
由于您当前的应用程序中没有线程,我建议您考虑使用Executor框架来并行化您的应用程序。在这两种情况下,您都必须创建Runnable实例。 JCIP一书提供了一个示例章节,可以帮助您解决这个问题。如果您不想最终创建25个以上的Runnable内部类,则可以创建一个uses reflection to invoke those methods for you的单个自定义Runnable类:
public ReflectiveRunnable {
private final Object target; // needs to be non-null
private final String methodName;
private final Object[] argValues;
private final Class[] argClasses;
public ReflectiveRunnable(Object target, String methodName, Object[] args) {
this.target = target;
this.methodName = methodName;
this.argValues = args;
this.argClasses = new Class[args.length];
for (int i = 0; i < args.length; i++) {
argClasses[i] = args[i].getClass();
}
}
public void run() {
try {
final Class cl = target.getClass();
final Method mthd=cl.getMethod(methodName, argClasses);
mthd.invoke(target, argValues);
} catch (final Exception e) {
// handle exception
e.printStackTrace();
}
}
}