Thread与Runnable的关系
经过一系列的分析之后可以发现,在多线程的实现过程之中已经有了两种方法:
Thread类、Runnable接口,如果从代码本身的结构说,使用Runnable是最方便的,因为其可以避免单继承的局限,同时也可以更好的进行功能的扩充。
但是从结构上也需要来观察Thread与Runnable的联系。
在JDK中查看Thread定义:
public class Thread exends Object implements Runnable{}
发现现在Thread类也是Runnable接口的子类,那么在之前继承Thread类的时候实际上还是复写的Runnable接口的run()方法,
多线程的设计之中,使用了代理设计模式的结构,用户自定义的线程主体只是负责项目核心功能的实现,而所有的辅助实现全部交由Thread类来处理。
多线程开发:
多线程开发的本质实质上是在于多个线程可以进行同一资源的抢占,那么Thread主要描述的是线程,而资源的描述是通过Runnable完成的
范例:利用卖票程序来实现多个线程的资源并发访问:
package cn.pjy.demo;
/**
* Thread与Runnable的关系
* 经过一系列的分析之后可以发现,在多线程的实现过程之中已经有了两种方法:
* Thread类、Runnable接口,如果从代码本身的结构说,使用Runnable是最方便的,因为其可以避免单继承的局限,同时也可以更好的进行功能的扩充。
*
* 但是从结构上也需要来观察Thread与Runnable的联系。
* 在JDK中查看Thread定义:
*
* public class Thread exends Object implements Runnable{}
*
* 发现现在Thread类也是Runnable接口的子类,那么在之前继承Thread类的时候实际上还是复写的Runnable接口的run()方法,
*
* 多线程的设计之中,使用了代理设计模式的结构,用户自定义的线程主体只是负责项目核心功能的实现,而所有的辅助实现全部交由Thread类来处理。
*
* 在进行thread启动多线程的时候调用的是start()方法,而后找到的是run()方法。
* 但通过Thread类的构造方法传递了一个Runnable接口对象的时候,那么该接口对下个将被Thread类中的target属性所保存。
* 在start()方法执行的时候会调用Thread类中的run()方法,而这个run()方法区调用Runnable接口子类被覆写过的run()方法。
*
* 多线程开发的本质实质上是在于多个线程可以进行同一资源的抢占,那么Thread主要描述的是线程,而资源的描述是通过Runnable完成的
*
*
* @author PJY
*
*/
class MyThread2 implements Runnable{
private int ticket = 5; //剩余票数
/*
* private String title;
*
* public MyThread2(String title) { this.title = title; }
*/
@Override
public void run() {
for(int x = 0; x < 100; x++) {
if(this.ticket > 0) {
System.out.println("卖票,ticket = " + this.ticket --);
}
}
}
}
public class Runnable_Thread {
public static void main(String[] args) {
MyThread2 mt = new MyThread2();
new Thread(mt).start(); //第一个线程启动
new Thread(mt).start(); //第二个线程启动
new Thread(mt).start(); //第三个线程启动
}
}
内存分析图: