我尝试在Java GUI应用程序中实现多线程,以便在运行几个密集方法时释放接口。我主要来自C#开发背景,并且在该环境中使用了几次Threads,并没有太多困难。
大致是:
C#
现在进入Java应用程序本身,它是一个GUI应用程序,有几个按钮执行不同的操作,应用程序使用MIDI API播放MIDI音符,我有播放,停止和添加单个音符等功能。 (需要注意的一点是,我不播放MIDI文件,而是手动创建音符/消息,通过音轨播放)。
我想在自己的线程中运行三个特定的操作
我有一个名为MIDIControl的类,它包含所有必要的功能,例如播放,停止和生成我需要的消息的实际操作。在FooView.Java类中为GUI表单本身创建了此对象的实例,这意味着例如:
我已经看过通过Java实现线程,并且我已经看到它以与C#方法不同的方式完成,有人可以向我解释如何在我的线程中实现线程情况?
如果有必要,我可以提供代码示例,感谢您的时间。
答案 0 :(得分:6)
Java线程的创建方式与C#线程相同,只是您将线程传递给Runnable
实现而不是委托。 (因为Java不支持委托)
答案 1 :(得分:3)
Java Concurrency in Practice是您的向导。请看SwingWorker。请记住,所有与UI相关的更改(组件模型或其属性)应始终在Event Dispatch Thread上完成。
答案 2 :(得分:2)
Java GUI应用程序中的后台任务通常使用SwingWorker类来完成,该类是专门为此目的而设计的。
答案 3 :(得分:2)
您需要区分更新GUI的任务和不更新GUI的任务。
如果您的任务需要更新GUI元素,例如您的任务(2),则需要对SwingWorker进行子类化。处理代码(调用您的exising库)将覆盖doInBackground()
,通过publish()
发送任何数据。然后,您的SwingWorker process()
覆盖可以与您的Swing组件进行交互。
原因:Swing不是线程安全的,因此如果从Event Dispatch Thread(EDT)以外的线程访问它,它可能会中断。 process()
将在美国东部时间开展。
对于不更新GUI的任务,创建一个实现Runnable
的新类,并在run()
方法中插入相应的MIDI库代码调用。然后,您可以将此作为目标传递给new Thread(myRunnable).start()
中的新线程。
答案 4 :(得分:1)
正如其他人所说的那样,你所使用的是SwingWorker类,这将使swing组件能够触发另一个线程中的任务,并以线程安全的方式通知它的完成和进度。你不能只使用原始线程可运行对象来喷出随机线程,然后期望通过这些线程与swing进行交互; swing通过设计不是线程安全的,所以通过这种方式做事你几乎肯定会在你的代码中引入细微的线程错误。
根据您使用的Java版本,您可以单独下载SwingWorker,也可以使用API中内置的。
如果您使用的是Java 6(或更高版本),则swing worker位于核心API here中。
如果您使用的是Java 5,那么Java 6版本已被反向移植here。
如果您使用的是早期版本,那么您必须添加sun的原始版本here。