前言
JavaFX是单线程编程,怎么个意思呢?意思就是所有对界面的操作都会交给唯一的线程Application Thread去处理,比如你要修改按钮一的名称,同时又要添加个按钮二,然后还要干点别的,那么不好意思,操作界面的线程只有一个,大家排队一个一个来。
1、我为什么要在JavaFX中使用多线程编程?
答:其实我主要是为了解决很多时候的卡顿问题(这个本应该说是用延迟加载来解决,但延迟加载离不开多线程思想)。
比如:打开一个页面同时加载数据会很卡(因为加载数据紧随页面初始化的动作)这样给人的体验很不友好,怎么解决呢,网上很多人都会用javafx.concurrent包下的Task来实现,这是一种解决方案。
但开始时我说了我主要是为了解决卡顿问题,那么既然卡顿是因为某两个动作连续执行造成的,那么我们可以将后面的动作延迟一下,同样可以解决卡顿的问题,比如我们先让页面初始化,接着延迟1秒来加载数据,所以时间轴动画也可以用来实现某些场合下的多线程编程效果。
当然多线程还能解决很多问题,比如一个很耗时的网络请求等等。
2、为什么把延迟加载跟多线程放一起说
答:因为延迟加载离不开多线程的支持。
3、实例-1:使用Platform.runLater(...)实现多线程
javafx.application包下的亲儿子,原理是把你要执行的动作添加到类似队列中,等Application Thread线程空闲时处理,说到底还是主线程(Application Thread)处理的,你的那个线程只负责给等待队列扔了一下。
下面用两个按钮来演示多线程(其实下面这种情况没必要用多线程,只是为了举例),一个演示错误用法,一个演示正确用法。
package zkh.javafx.learn.concurrent;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
* 多线程
*/
//继承javafx.application.Application是JavaFX的开始
public class Concurrent1 extends Application {
/**
* Stage:就是你能看到的整个软件界面(窗口)
* Scene:就是除了窗口最上面有最大、最小化及关闭按钮那一行及窗口边框外其它的区域(场景)
* 场景(Scene)是一个窗口(Stage)必不可少的
*/
@Override
public void start(Stage stage) throws Exception {
VBox vBox = new VBox(); vBox.setAlignment(Pos.CENTER);
final Button button1 = new Button("我是按钮1");
button1.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
Thread button1thread = new Thre