一个进程(Process)是一个包括有自身执行地址的程序,在一个多任务的操作系统中,可以分配CPU时间给每一个进程,CPU在片段时间中执行某个进程,然后下一个时间片段跳至另一个进程去执行,由于转换速度很快,这使得每个程序像是在同时进行处理一般。
一个执行绪是进程中的一个执行流程,一个进程中可以同时包括多个执行绪,也就是说一个程序中同时可能进行多个不同的子流程,这使得一个程序可以像是同时间 处理多个事务,例如一方面接受网络上的数据,另一方面同时计算数据并显示结果,一个多执行绪程序可以同时间处理多个子流程。
在Java中要实现执行绪功能,可以实作Runnable接口,Runnable接口中只定义一个run()方法,然后实例化一个 Thread对象时,传入一个实作Runnable接口的对象作为自变量,Thread对象会调用Runnable对象的run()方法,进而执行当中所定义的流程。
下面这个程序是个简单的Swing程序,您可以看到如何实作Runnable接口及如何启动执行绪:
package onlyfun.caterpillar; import javax.swing.*; import java.awt.BorderLayout; import java.awt.Graphics; import java.awt.event.*; public class ThreadDemo extends JFrame { public ThreadDemo() { // 配置按钮 JButton btn = new JButton("Click me"); // 按下按钮后绘制圆圈 btn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Thread thread1 = new Thread(new Runnable() { public void run() { Graphics g = getGraphics(); for(int i = 10; i < 300; i+=10) { try { Thread.sleep(500); g.drawOval(i, 100, 10, 10); } catch(InterruptedException e) { e.printStackTrace(); } } } }); Thread thread2 = new Thread(new Runnable() { public void run() { Graphics g = getGraphics(); for(int i = 10; i < 300; i+=10) { try { Thread.sleep(500); g.drawOval(i, 150, 15, 15); } catch(InterruptedException e) { e.printStackTrace(); } } } }); thread1.start(); thread2.start(); } }); getContentPane().add(btn, BorderLayout.NORTH); // 取消按下窗口关闭钮预设动作 setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE); setSize(320, 200); setVisible(true); } public static void main(String[] args) { new ThreadDemo(); } }
将程序编译并执行时,您可以看到一个窗口,按下上面的按钮,您会看到两个圆在「同时」绘制,虽说是同时,其实也只是错觉而已,其实是CPU往来两个流程之间不断的进行绘制圆的动作而已。
Thread类别也实作了Runnable接口,您也可以继承Thread类别并重新定义它的run()方法,好处是可以使用Thread上的一些继承下来的方法,例如yield(),然而继承了Thread就表示您不能让您的类别再继承其它的类别。