---------------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. NSAttributedStringKey

    NSFontAttributeName; //字体,value是UIFont对象 NSParagraphStyleAttributeName;//绘图的风格(居中,换行模式,间距等诸多风格),valu ...

  2. 【leetcode刷题笔记】Reverse Words in a String

    Given an input string, reverse the string word by word. For example,Given s = "the sky is blue& ...

  3. Redis高级进阶(一)

    一.redis中的事务 在关系型数据库中事务是必不可少的一个核心功能,生活中也是处处可见,比如我们去银行转账,首先需要将A账户的钱划走,然后存到B账户上,这两个步骤必须在同一事务中,要么都执行,要么都 ...

  4. Python3 函数 一

    什么是函数? 函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,编程中的函数在英文中也有很多不同的叫法.在BASIC中叫做subroutine(子过程或子程序),在Pascal ...

  5. Cache-Control常用类型

    可缓存性 no-cache 强制所有缓存了此响应的缓存用户,在使用已存储的缓存数据前,发送条件请求到原始服务器,若未过期,则使用缓存数据,否则重新获取 no-store 不存储有关客户端请求或服务器响 ...

  6. 第三篇、javascript整数和字符串

    一.整数 JavaScript中不区分整数值和浮点数值,JavaScript中所有数字均用浮点数值表示. 转换: parseInt(..)    将某值转换成数字,不成功则NaN parseFloat ...

  7. 通过vSphere API获取对象Statistics

    预备知识点: 1.vim.PerformanceManager.MetricId()    通过counter_id获取到metric_id 2.vim.PerformanceManager.Quer ...

  8. how to close the old Session - if the same username starts a new Session?

    Question: want to close the old Session - if the same username starts a new Session Any ideas how i ...

  9. 算法(Algorithms)第4版 练习 1.5.22

    package com.qiusongde; import edu.princeton.cs.algs4.StdOut; import edu.princeton.cs.algs4.StdStats; ...

  10. 用eclipse写xml文件

    1. 2.把写好的xml文件粘贴到src文件夹中.