线程是独立于当前程序的运行过程。那么在什么时候需要使用多线程呢?考虑下面的例子。
你在一个GUI程序中放了一个球,这个球会向固定的地方运动,当碰到墙壁的时候回反弹,你写了这个程序。
Ball ball = new Ball();
panel.add(ball);
for(int i = 0;i != STEPS;i++)
{
ball.move(panel.getBounds());
panel.paint(panel.getGraphics());
Thread.sleep(DELAY);
}
Thread的sleep函数是为了保证球不反弹地太快,导致你看不见。
如果你运行这个程序,球可以反弹,很棒,但是它完全接管了你的程序,在求弹完之前,你没有办法停止这个程序。
很显然,你不希望这样。你希望他能够在其他时间做这些耗费时间的工作,而且需要能够被打断。毕竟,当你在上网的时候,打断一个正在下载的文件是在正常不过的事。在这种情况下,你需要考虑使用在另外一个线程中执行任务。
使用多线程给其他任务一个机会
我们需要改进我们的程序,使控制球的代码在另外一个线程中运行。我们使用小球的案例作为介绍,在实际中,你需要考虑所有长时间运算的代码。
下面是将代码在另外一个线程中运行的方法。
- 将你的代码放到一个实现了Runnable接口的类的run方法中。这个接口非常简单,只有一个方法
public interface Runnable
{
void run();
}
你可以使用下面的代码实现这个接口
class MyRunnable implements Runnable
{
public void run()
{
taskcode;
}
}
- 构造一个对象
Runnable r = new MyRunnable();
- 使用这个对象构造一个Thread对象。
Thread t = new Thread(r);
- 启动线程
t.start();
为了让我们的弹球程序更好,我们将它放到单独的线程中。
class BallRunnable implements Runnable
{
...
public void run()
{
try
{
for(int i = 1;i <= STEPS;i++)
{
ball.move(component.getBounds());
component.repaint();
Thread.sleep(DELAY);
}
}
catch(InterruptedException exception)
{
}
}
}
我们会在之后讨论InterruptedException异常。
每次点击开始按钮,都会创建一个新线程。
Ball b = new Ball();
panel.add(b);
Runnable r = new BallRunnable(b,panel);
Thread t = new Thread(r);
t.start();
然后你已经达到了你的目标,下面需要了解线程之间怎么交互。
你可能也知道可以继承Thread类创建线程,但是这种方法已经不再推荐。此外,你需要记住,不要直接调用run方法,因为这样他们还是在同一个线程里面运行,你要调用的是start方法。