您好我正在尝试理解EDT与多线程,希望如果没有意义,有人可以纠正我。
首先,我将GUI的创建过程放在自己的线程中 然后加入EDT
public class Main
{
static ServerGui serverGui;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try{
serverGui = new ServerGui();
serverGui.frame.setVisible(true);
}
catch(Exception e)
{
e.printStackTrace(); }} });}}
在我的GUI中,我创建了ServerDataHandler对象sdh
public class ServerGui {
public ServerDataHandler sdh = new ServerDataHandler();
public JFrame frame;
public ServerGui() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setType(Type.NORMAL);
frame.setBounds(100, 100, 800, 600); } }
现在从另一个线程,我希望使用该sdh对象,并使用一些方法 它有..例如sdh.writeToFile();所以这是我的问题
因为我想使用同一个对象,我需要这样做,就像我在下面一样吗?。
我是否需要同步ServerDataHandler类,例如在我的情况下,该方法写入文件?我怀疑我做了
我什么时候需要使用'invokeLater'?就在我正在改变实际的GUI时?
客户
public class Client implements Runnable {
private Socket clientSocket;
public Client(Socket clientSocket) {
this.clientSocket = clientSocket;
@Override
public void run() {
Main.serverGui.sdh.writeToFile();} }
答案 0 :(得分:0)
类和对象
您创建的Main,Client,ServerGui和ServerDataHandler类就是那些类。当您调用类的构造函数时,您将创建一个对象,该对象是该类的实例。
每个线程在JVM中的对象之间编织,遵循执行路径,因为一个对象中的方法调用另一个对象中的方法。所以对象只是放在JVM中,而不是专门绑定到线程。
<强>线程强>
在JVM里面还有多个线程。您可以使用java.lang.Thread
类中的方法自行创建和销毁它们。但主线程和事件调度线程是为您创建的。
可以在一个线程中创建一个Runnable
类实例的对象,然后将其移交给另一个线程运行。这是您拨打SwingUtilities.invokeLater
时的操作。您创建一个匿名Runnable
对象并安排其事件调度线程调用其run()
方法。
事件调度线程
这样做的原因是Swing对象不是线程安全的,即一次写入不被多个线程处理。像setVisible(true)
这样的方法应该由Event Dispatch Thread调用,一次一个。
将在Event Dispatch Thread上调用分配给Swing对象的侦听器中的事件处理方法。当他们被调用时,事件调度线程正在忙着编织事件处理程序代码,并且无法在屏幕上绘制像素或对按钮点击作出反应。因此,如果您希望用户界面具有响应性,则应保持事件处理代码的简短快捷。
如果要运行冗长的任务,例如读取长文件或与服务器聊天,则应创建并启动新线程以运行此任务。这称为后台或工作线程。您可以为要运行的作业创建Runnable类,并将其提供给您创建的Thread。
一种更高级的计划任务方法是通过java.util.concurrent包中的类,特别是ExecutorService。
包含更多信息的好教程是Concurrency in Swing