构造线程的另外一种方法是实现Runnable接口。通常一个类已经扩展了Frame或Applet,由于Java语言的单继承性,这样就不能再继承Thread类。我们就可以用实现Runnable接口来构造线程。
Runnable接口的定义中只包含一个抽象方法 ,即:
Public interface Runnable{
Public abstract void run();
}
实现Runnable接口构造线程的步骤如下:
①将需要实现多线程的类声明为实现Runnable接口的类,实现run()方法,并将线程体放在该方法中。
②创建一个该类的实例。
③从该实例创建一个Thread的实例。
④调用start()方法启动该线程。
将前面的例子用第二种方法改写如下:
public class Main {
public static void main(String[] args) {
System.out.println("starting main");
A r1=new A("thread1");
Thread t1=new Thread(r1);
t1.start();
A r2=new A("thread2");
Thread t2=new Thread(r2);
t2.start();
A r3=new A("thread3");
Thread t3=new Thread(r3);
t3.start();
System.out.println("main is done");
}
}
public class A implements Runnable{
String treadId;
public A(String treadId){
this.treadId=treadId;
}
public void run() {
System.out.println("\n Thread started:"+this.treadId);
for (int i=0;i<6;i++){
System.out.println("i="+(i+1)+"\t");
}
System.out.println("\n Thread spotted:"+this.treadId);
}
}
运行结果与上例相同。
因为Runnable接口和Thread类之间没有继承关系,所以不能直接赋值,为了使run()方法中的代码在单独的线程中运行,还需要一个Thread的实例实现对Runnable对象的包装。为此,线程中需要包括两部分内容:Thread提供线程的支持;Runnable实现类提供线程执行体。
下面是利用Runnable实现卖票的简单代码:
public class Main {
public static void main(String[] args) {
Service1 s=new Service1();
Thread t=new Thread(s,"窗口1");
t.start();
Thread t1=new Thread(s,"窗口2");
t1.start();
}
}
public class Ticket extends Thread {
int tickrt;
public Ticket(){}
public Ticket(int tickrt){
this.tickrt=tickrt;
}
public int getTickrt() {
return tickrt;
}
public void setTickrt(int tickrt) {
this.tickrt = tickrt;
}
}
public class Service1 implements Runnable{
Ticket ticket=new Ticket(10);
public Service1(){}
public Service1(Ticket ticket){
this.ticket=ticket;
}
public void sale() {
if (ticket.getTickrt() > 0) {
System.out.println(Thread.currentThread().getName() + " " + "正在卖第" + ticket.getTickrt() + "张票");
int num = ticket.getTickrt();
num--;
ticket.setTickrt(num);
}
}
public void run(){
while(ticket.getTickrt()>0){
sale();
}
}
}