首页 > 其他 > 详细

Computer Science III Thread

时间:2015-03-27 12:41:45      阅读:116      评论:0      收藏:0      [点我收藏+]

在java中可有两种方式实现多线程:
1. 继承Thread类
2. 是实现Runnable接口

由于Java不支持多继承,所以推荐使用实现Runnable接口的方法。

如果想要新建一个线程类,那么只需要override run() method就好了。

实现Runnable的类在创建新线程的时候用 Tread tread = new Tread(实现Runnable接口的类),就完成了Tread的创建。

 

技术分享

 

 - State transitions of a thread

Thread类的两个主要method: start() 和 run()的区别

start() 
  - 让thread进入 runnable 状态
  - call run() method
  - extend Thread Class不用override start() method

run()
  - 当thread运行时被调用
  - run()在thread创建完了之后被调用
  - Runnable类里的run()没有任何内容,所以一定要实现

 

  • GUI和Threads

  在Java中,GUI的绘制和事件的处理都是集中在一个线程之中完成的,这个线程叫做Event Dispatcher Thread - 事件分发线程 简称EDT

  我在CSDN上发现了一个关于Swing EDT的很好的文章 【Java线程】Swing事件分发线程EDT与SwingUtilities.invokeLater 
  "EDT:Swing程序只有一个EDT,该线程负责GUI组件的绘制和更新,通过调用程序的事件处理器来响应用户交互。所有事件处理都是在EDT上进行的,程序同UI组件和其基本数据模型的交互只允许在EDT上进行,所有运行在EDT上的任务应该尽快完成,以便UI能及时响应用户输入。"
  简单来说EDT机制是为了防止GUI的绘制和事件互相影响(interrupted)。

  为什么要在这里谈到EDT呢?

  因为下面一个概念不是很好理解(至少javadoc写得很模糊): Platform.runLater(): 如果你有多个线程,其中包括一个GUI线程(也就是EDT),一个是没有GUI的线程。比如说你需要完成一个进度条,但是如何才能让进度(非GUI线程)和进度条(GUI线程)相互关联呢?那么Platform.runlater()就很有用了。

  Platform.runlater()的具体实现也有主要两种方法,比如说我们想要创建一个从1数到1,000,000的进度条:

  第一种写法是这样的:

Code using PlatForm.RunLater :

final ProgressBar bar = new ProgressBar();
new Thread(new Runnable() {
    @Override public void run() {
        for (int i=1; i<=1000000; i++) {
            final int counter = i;
            Platform.runLater(new Runnable() {
                @Override public void run() {
                    bar.setProgress(counter/1000000.0);
                }
            });
        }
    }
}).start();

第一种写法其实是一种很反人类的写法,你的脑子会因为两个Runnable多死几个细胞!

 

第二种实现是:

Code using Task :

Task task = new Task<Void>() {
    @Override public Void run() {
        static final int max = 1000000;
        for (int i=1; i<=max; i++) {
            updateProgress(i, max);
        }
        return null;
    }
};
ProgressBar bar = new ProgressBar();
bar.progressProperty().bind(task.progressProperty());
new Thread(task).start();

这样的写法就简洁很多。
具体的讨论详见stackoverflow: Platform.Runlater and Task Javafx

 

但不是说我们不能用Platform.runlater(),下面是一个使用Platform.runlater()实现进度条的例子。

技术分享
import java.util.concurrent.locks.ReentrantLock;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;


public class BetterProgressTest extends Application {
    ProgressBar bar;
    ProgressIndicator indicator;
    Button button;
    Label processLabel;
    int numTasks = 0;
    ReentrantLock progressLock;

    @Override
    public void start(Stage primaryStage) throws Exception {
        progressLock = new ReentrantLock();
        VBox box = new VBox();

        HBox toolbar = new HBox();
        bar = new ProgressBar(0);      
        indicator = new ProgressIndicator(0);
        toolbar.getChildren().add(bar);
        toolbar.getChildren().add(indicator);
        
        button = new Button("Restart");
        processLabel = new Label();
        processLabel.setFont(new Font("Serif", 36));
        box.getChildren().add(toolbar);
        box.getChildren().add(button);
        box.getChildren().add(processLabel);
        
        Scene scene = new Scene(box);
        primaryStage.setScene(scene);

        button.setOnAction(e -> {
                Task<Void> task = new Task<Void>() {
                    int task = numTasks++;
                    double max = 200;
                    double perc;
                    @Override
                    protected Void call() throws Exception {
                        try {
                            progressLock.lock();
                        for (int i = 0; i < 200; i++) {
                            System.out.println(i);
                            perc = i/max;
                            
                            // THIS WILL BE DONE ASYNCHRONOUSLY VIA MULTITHREADING
                            Platform.runLater(new Runnable() {
                                @Override
                                public void run() {
                                    bar.setProgress(perc);
                                    indicator.setProgress(perc);
                                    processLabel.setText("Task #" + task);
                                }
                            });

                            // SLEEP EACH FRAME
                            //try {
                                Thread.sleep(10);
                           // } catch (InterruptedException ie) {
                          //      ie.printStackTrace();
                          //  }
                        }}
                        finally {
                                progressLock.unlock();
                                }
                        return null;
                    }
                };
                // THIS GETS THE THREAD ROLLING
                Thread thread = new Thread(task);
                thread.start();            
        });        
        primaryStage.show();
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}
BetterProgressTest

  例子里面用到了Task类,关于Java并发的内容并不是很熟悉,就不深入研究了。

 

如何结果(kill)掉一个线程?

  常见的做法是设置一些条件(loop, exception)来让thread在运行达到一定结果之后终止(自我毁灭)。

 

  • Timer和TimerTask 用来创建和时间相关的类

  - Need program to do something X times/second
  - TimerTask可以看做第三种实现线程的方式(extend threads 和 implement Runnable之外)
    "Timer和TimerTask可以做为实现线程的第三种方式,前两中方式分别是继承自Thread类和实现Runnable接口。
    Timer是一种线程设施,用于安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行,可以看成一个定时器,可以调度TimerTask。TimerTask是一个抽象类,实现了Runnable接口,所以具备了多线程的能力。"  Java线程(五):Timer和TimerTask

Computer Science III Thread

原文:http://www.cnblogs.com/zeqli/p/4371221.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!