用多线程实现反应灵敏的界面(Java)

  “多线程最主要的一个用途是构建一个”反应灵敏“的界面”

                        --摘自《Java编程思想》

  为了理解上面这句话,我们可以假设一种情景:假设有一个程序,该程序用来处理大量的数学运算,在多数情况下会占用大量的cpu时间,

而在处理数据的过程中又尝尝需要与用户进行交互,而如果进程中只有一个主线程的话,那么程序每次都需要等到该主线程的任务完成后

才能对界面操作进行响应,这在通常的情况下是不可接受的。我们可以设想一个情景就是在程序运行时,如果突然有事需要离开(导师请你

出去吃饭,机会难得),这时你可能就需要点击关闭按钮,关闭程序,但是程序却说我这还有200次循环要跑,没空理你,等会我。如果遇到这种

情况,我们也有办法,打开任务管理器,结束进程,简单有效但是却很暴力。

  接下来我们会举两个例子,一个是单线程对界面反应迟钝的例子,一个是多线程(双线程)对界面反应灵活的例子。

  程序界面为下图,大致流程是当我们点击start按钮后,程序从0开始自增计数,并把结果显示在输入框中,而当我们点击Toggle按钮时,计数暂停,

再次点击计数恢复。

  为了体现单线程与多线程的差异,我们把这个计数的过程定义为一个死循环,即从0自增到无穷大,而Toggle按钮则可以用来暂停这个循环。在例子一中

只有一个主线程,这就导致在计数循环时,程序不能够对点击按钮的操作进行相应,我们也无法关闭该窗口。为了解决这个问题,在例子二中我们把这个计数

的过程放到一个单独的线程中,而主线程则专门用来响应界面的操作,这时程序就可以正常运行。

  

 (1)例子1

  
package hongqi.daiwei.lianyuan.java.multithread;

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Counter1 extends Applet {
    private int count = 0;
    private Button onOff = new Button("Toggle");
    private Button start = new Button("Start");
    private TextField t = new TextField(10);
    private boolean runFlag = true;
    
    public void init() {
        add(t);
        start.addActionListener(new StartL());
        add(start);
        onOff.addActionListener(new OnOffL());
        add(onOff);
        super.init();
    }
    
    public void go(){
        while(true){
            try {
                Thread.currentThread();
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(runFlag){
                t.setText(Integer.toString(count++));
            }
        }
    }
    
    class StartL implements ActionListener{
        public void actionPerformed(ActionEvent e) {
            go();
        }
    }
    
    class OnOffL implements ActionListener{
        public void actionPerformed(ActionEvent e) {
            runFlag = !runFlag;
        }
    }
    
    public static void main(int argv, String argc[][]){
        Counter1 applet = new Counter1();
        Frame aFrame = new Frame("Counter1");
        aFrame.add(applet, BorderLayout.CENTER);
        aFrame.setSize(300, 200);
        applet.init();
        applet.start();
        aFrame.setVisible(true);
        aFrame.addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
            
        });
        
    }
}
View Code

 (2)例子2

  线程类:

package hongqi.daiwei.lianyuan.java.multithread;

public class SeparateSubTask extends Thread {
    
    Counter2 c = null;
    private boolean flag = true;
    private int count = 0;

    public SeparateSubTask(Counter2 c){
        this.c = c;
        this.start();
    }
    
    public void invertFlag(){
        flag = !flag;
    }
    
    public void run() {
        while(true){
            try {
                sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(flag){
                c.t.setText(Integer.toString(count++));
            }
        }
    }
    
}
View Code

  主类:

package hongqi.daiwei.lianyuan.java.multithread;

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Counter1 extends Applet {
    private int count = 0;
    private Button onOff = new Button("Toggle");
    private Button start = new Button("Start");
    private TextField t = new TextField(10);
    private boolean runFlag = true;
    
    public void init() {
        add(t);
        start.addActionListener(new StartL());
        add(start);
        onOff.addActionListener(new OnOffL());
        add(onOff);
        super.init();
    }
    
    public void go(){
        while(true){
            try {
                Thread.currentThread();
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(runFlag){
                t.setText(Integer.toString(count++));
            }
        }
    }
    
    class StartL implements ActionListener{
        public void actionPerformed(ActionEvent e) {
            go();
        }
    }
    
    class OnOffL implements ActionListener{
        public void actionPerformed(ActionEvent e) {
            runFlag = !runFlag;
        }
    }
    
    public static void main(int argv, String argc[][]){
        Counter1 applet = new Counter1();
        Frame aFrame = new Frame("Counter1");
        aFrame.add(applet, BorderLayout.CENTER);
        aFrame.setSize(300, 200);
        applet.init();
        applet.start();
        aFrame.setVisible(true);
        aFrame.addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
            
        });
        
    }
}
View Code

  

原文地址:https://www.cnblogs.com/liujinyao/p/4687745.html