---------------siwuxie095

 
 

 
 

 
 

 
 

 
 

 
 

 
 

Java 程序的主线程

 
 

当 Java 程序启动时,一个线程立刻运行,该线程通常叫做程序的

主线程(main Thread),因为它是程序开始时就执行的

 
 

 
 

一般来说,某个类中会有一个
main 函数,当程序启动时,

该函数就会第一个自动得到执行,并成为程序的主线程

 
 

 
 

主线程的特征如下:

 
 

·
主线程是产生其他子线程的线程

 
 

·
主线程中执行程序的控制

 
 

·
通常主线程必须最后完成执行,因为它执行各种关闭动作

 
 

 
 

『永远不要在主线程中直接操作界面』

 
 

 
 

 
 

 
 

 
 

Swing 的 UI 线程

 
 

Swing API 的设计目标是强大、灵活和易用

 
 


Swing 组件不支持多线程访问,程序要操作 或 更改界面内容,

必须向单一线程执行请求,把这个单一的线程称为事件派发线程

(可简称为
UI 线程)

 
 

这意味着
Swing 是线程不安全的,所有对于 UI 元素的修改都必须

提交给
UI 线程执行,不能在主线程 或 其他任何线程中直接操作 UI

的内容

 
 

如果要从
UI 线程 或 绘制代码以外的地方 访问 UI,需要使用 SwingUtilities 类


invokeLater() 或 invokeAndWait() 方法

 
 

如果要处理一些耗费大量计算能力


I/O 能力限制的工作,可以使用一个

线程工具类,如:SwingWorker 或 Timer

 
 

 
 

 
 

 
 

 
 

如:

 
 

工程名:SwingThreadSafeTest

包名:com.siwuxie095.swingthread

类名:BadDemo.java、GoodDemo.java、NewFrame.java

 
 

 
 

工程结构目录如下:

 
 

 
 

 
 

 
 

BadDemo.java:

 
 

package com.siwuxie095.swingthread;

 
 

import javax.swing.JFrame;

 
 

/**

* 错误,不可以在主线程中创建UI元素

更改UI属性

*

* @author siwux

*

*/

 
 

public class BadDemo {

 
 

public static
void main(String[] args) {

 

JFrame frame=new JFrame();

frame.setTitle("这是一个窗口");

frame.setSize(500,200);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setVisible(true);

}

 
 

}

 
 

 
 

 
 

GoodDemo.java:

 
 

package com.siwuxie095.swingthread;

 
 

import javax.swing.JFrame;

import javax.swing.SwingUtilities;

 
 

/**

* 虽然效果相同,但窗体的创建和其属性的设定都变成了线程安全的操作

*

* SwingUtilities.invokeLater()的底层实际上就是EventQueue.invokeLater()

*

* EventQueue 即事件派发线程,即 UI 线程

*

* @author siwux

*

*/

 
 

public class GoodDemo {

 

public static
void main(String[] args) {

 

//在主方法中如果要创建一个新的窗体元素,可以通过静态方法

//调用 SwingUtilities类的 invokeLater() 方法,传入匿名对象 new Runnable()

SwingUtilities.invokeLater(new Runnable() {

 

@Override

public
void run() {

JFrame frame=new JFrame();

frame.setTitle("这是一个窗口");

frame.setSize(500,200);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setVisible(true);

}

});

}

 
 

}

 
 

 
 

 
 

NewFrame.java:

 
 

package com.siwuxie095.swingthread;

 
 

import java.awt.BorderLayout;

import java.awt.EventQueue;

 
 

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.border.EmptyBorder;

 
 

//NewFrame 直接继承自 JFrame

public class NewFrame extends JFrame {

 
 

private JPanel contentPane;

 
 

/**

* Launch the application.

*

* EventQueue.invokeLater() 是窗体创建是自带的方法

*/

 

public static
void main(String[] args) {

EventQueue.invokeLater(new Runnable() {

public
void run() {

try {

NewFrame frame = new NewFrame();

frame.setVisible(true);

} catch (Exception e) {

e.printStackTrace();

}

}

});

}

 
 

/**

* Create the frame.

*/

public NewFrame() {

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setBounds(100, 100, 450, 300);

contentPane = new JPanel();

contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

contentPane.setLayout(new BorderLayout(0, 0));

setContentPane(contentPane);

}

 
 

}

 
 

 
 

 
 

对比 BadDemo.java 和 GoodDemo.java:

 
 

虽然效果一样,但不能在主线程中直接创建
UI
元素 或 更改
UI
属性,这是线程不安全的

 
 

而使用
SwingUtilities.invokeLater()
方法,在其中创建窗体和设定属性就是线程安全的

 
 

 
 

 
 

对比
GoodDemo.java 和 NewFrame.java:

 
 

效果不谈(次要),主要看其主方法中的实现,如下:

 
 

GoodDemo.java 使用 SwingUtilities.invokeLater() 方法

 
 

 
 

 
 

NewFrame.java 使用 EventQueue.invokeLater() 方法

 
 

 
 

 
 

SwingUtilities
属于
javax.swing.SwingUtilities
类,


EventQueue
属于
java.awt.EventQueue

 
 

二者作用完全相同

 
 

「EventQueue
即事件派发线程,也即 UI 线程」

 
 

 
 

 
 

实际上
SwingUtilities.invokeLater()
的底层就是
EventQueue.invokeLater()

 
 

 
 

 
 

 
 

 
 

一般情况下,如果将窗体创建为一个新的类对象(即类似于这里的
NewFrame.java),

想要在另外一个类中调用,而不在窗体程序中进行调用,可以将窗体程序中自动生成的

主方法代码剪切过去

 
 

 
 

 
 

 
 

 
 

 
 

【made by siwuxie095】

主线程与UI线程简介的更多相关文章

  1. C# 委托 / 跨线程访问UI / 线程间操作无效: 从不是创建控件“Form1”的线程访问它

    C# 委托 / 跨线程访问UI /  线程间操作无效: 从不是创建控件“Form1”的线程访问它 网上的代码都比较复杂,还是这个简单 见代码, 简易解决办法: 主窗体代码 using System; ...

  2. 新建线程与UI线程间的通信

    现在用一个实例来演示一下自己的新建线程与UI线程间的通信. UI界面包含3个控件: 一个输入框,用来输入数字: 一个显示框,用来显示从2开始,到输入数字之间的所有质数: 一个按钮,点击后获取输入框输入 ...

  3. [Android学习笔记]子线程更新UI线程方法之Handler

    关于此笔记 不讨论: 1.不讨论Handler实现细节 2.不讨论android线程派发细节 讨论: 子线程如何简单的使用Handler更新UI 问题: android开发时,如何在子线程更新UI? ...

  4. OkHttp3几个简单的例子和在子线程更新UI线程的方法

    okHttp用于android的http请求.据说很厉害,我们来一起尝尝鲜.但是使用okHttp也会有一些小坑,后面会讲到如何掉进坑里并爬出来. 首先需要了解一点,这里说的UI线程和主线程是一回事儿. ...

  5. Android ActivityThread(主线程或UI线程)简介

    1. ActivityThread功能 它管理应用进程的主线程的执行(相当于普通Java程序的main入口函数),并根据AMS的要求(通过IApplicationThread接口,AMS为Client ...

  6. C#用副线程改主线程(UI线程)的控件属性的方法(包括Winform和WPF)

    C#用副线程去试图修改主线程的UI控件会报出异常,解决方案是使用副线程注册事件通知主线程自己去修改UI控件 在winform中,方法如下 private void button1_Click(obje ...

  7. C#中后台线程和UI线程的交互

    在C#中,从Main()方法开始一个默认的线程,一般称之为主线程,如果在这个进行一些非常耗CPU的计算,那么UI界面就会被挂起而处于假死状态,也就是说无法和用户进行交互了,特别是要用类似进度条来实时显 ...

  8. WPF线程获取UI线程

    WPF中只能是UI线程才可以改变UI控件相关,当采用多线程工作时,可用以下代码获取 UI线程进行操作: App.Current.Dispatcher.Invoke((Action)delegate() ...

  9. C#在非UI线程调用UI线程的控件

    首先需要定义一个委托(delegate): private delegate void delegateSetProcessBarVal(int value); 然后定义一个方法来执行具体的操作: p ...

随机推荐

  1. Java EE规范是如何制定的

    我们经常做的JAVA EE开发实际上都是遵从了JAVA EE的规范进行的,那么这些规范是如何制定的呢? 这就不得不提到JCP这个组织了. JCP( Java Community Process)可以翻 ...

  2. winform窗体取消最大化双击标题最大化

    实现目标,固定窗体大小,1.窗体标题去掉最大化按钮2.双击窗体标题也不会最大化,彻底取消最大化 问题,如果设置窗体MaximizeBox和MinimumSize属性,看似问题解决了,单随之而来的问题是 ...

  3. 【leetcode刷题笔记】Jump Game

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...

  4. uCGUI 按键窗口切换机制

    前段时间在做一个窗口项目,这个项目菜单项过多,在管理起来比较麻烦.想做一个高效移植又方便的一个切换机制.后来在网上多方查找这方面资料,但是感觉比较少.后来自己整理出了这个结构,希望对后来朋友有所帮助. ...

  5. 第十篇、模块一、sys\os\hashlib模块的应用

    一.模块分为三种 1)自定义模块 2)第三方模块 3)内置模块 如何导入模块? 下面两种: 1)import 模块名字  as 别名(重新给模块命名) 2)from  模块名字  import 功能( ...

  6. Linux 创建Bridge

    安装Bridge工具软件包 Linux可以工作在网桥模式,必须安装网桥工具bridge-utils,运行命令: yum install bridge-utils 或 apt-get install b ...

  7. Vim 分隔窗口

    一,分隔窗口: 打开文件时在:命令模型时下面输入:split 将分隔为上下2个窗口:默认上窗口为活动窗口,可以通过CTRL-w来来回切换窗口; :close 为关闭窗口,最后一个窗口不能关闭: :on ...

  8. <软件架构与设计模式>侯捷老师关于Adapter类在STL中的深入解析和模式探讨

    题外话:侯捷老师难得一年就来上九堂课就要会宝岛,特此留念签名赠语及合照以自勉.  学海无涯,为勤是岸 <正文开始> 昨天晚上连上了3个小时的大课探究单单讲了Adapter一个类,幸运的是本 ...

  9. 用用OGRE1.74搭建游戏框架(转载)

    用OGRE1.74搭建游戏框架(一) 新版的OGRE出来了,不知什么原因抛弃了CEGUI.国内的教程好像也更新比较少了,在官网上还是发现不少资料的,现在参考官网上的一些资料来搭建一个游戏的框架. 参考 ...

  10. javaScript-基础篇(一)

    1.如何插入JS 使用<script>标签在HTML网页中插入JavaScript代码.注意, <script>标签要成对出现,并把JavaScript代码写在<scri ...