实现Runnable接口
- 创建一个实现了Runnable接口的类
- 实现类去实现Runnable中的抽象方法:run()
- 创建实现的类的对象
- 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象。
- 通过Thread类的对象调用start()
代码
class MThread implements Runnable{
@Override
public void run() {
for(int i=0;i<100;i++){
if(i%2==0) System.out.println(i);
}
}
}
public class ThreadTest1 {
public static void main(String[] args) {
MThread mThread = new MThread();
Thread thread = new Thread(mThread);
thread.start();
}
}
多窗口卖票
class window1 implements Runnable{
private int ticket = 100;
@Override
public void run() {
while (true){
if(ticket>0){
System.out.println(Thread.currentThread().getName()+":卖票,票号为:"+ticket);
ticket--;
}else break;
}
}
}
public class WindowTest {
public static void main(String[] args) {
window1 w = new window1();
Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
创建方式的比较
开发中,优先选择实现runnable接口的方式。
原因:
- 实现的方式没有类的单继承性的局限性
- 实现的方式更适合来处理多个线程有共享数据的情况
联系
- 两种方式都需要重写run()方法,将线程要执行的逻辑声明在run()中
线程的生命周期
JDK中用Thread.State类定义了线程的几种状态。
Java语言使用Thread类及其子类的对象来表示线程,在它的一个完整的生命周期中通常要经历如下五种状态。
- 新建:当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态。
- 就绪:处于新建状态的线程被start()后,将进入线程队列等待CPU时间片,此时它已具备了运行的条件,只是没分配到CPU资源。
- 运行:当就绪的线程被调度并获得CPU资源时,便进入运行状态,run()方法定义了线程的操作和功能
- 阻塞:在某种特殊情况下,被人为挂起或执行输入输出操作时,让出CPU并临时中止自己的执行,进入阻塞状态;
- 死亡:线程完成了它的全部工作或线程被提前强制性地中止或出现异常导致结束。