大可制作:QQ群:31564239(asp|jsp|php|mysql)

Java Gossip: 实现 Runnable 接口

一个进程(Process)是一个包括有自身执行位址的程序,在一个多工的作业系统中,可以分配CPU时间给每一个进程,CPU在片段时间中执行某个进程,然后下一个时间片段跳至另一个进程去执行,由于转换速度很快,这使得每个程序像是在同时进行处理一般。

一个线程是进程中的一个执行流程,一个进程中可以同时包括多个线程,也就是说一个程序中同时可能进行多个不同的子流程,这使得一个程序可以像是同时间 处理多个事务,例如一方面接受网路上的数据,另一方面同时计算数据并显示结果,一个多线程程序可以同时间处理多个子流程。

在Java中要实现线程功能,可以实现Runnable接口,Runnable接口中只定义一个run()方法,然后实例化一个 Thread对象时,传入一个实现Runnable接口的对象作为参数,Thread对象会调用Runnable对象的run()方法,进而执行当中所定义的流程。

下面这个程序是个简单的Swing程序,您可以看到如何实现Runnable接口及如何启动线程:

  • ThreadDemo.java
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就表示您不能让您的类再继承其它的类。