2019.8.9 NIIT第二十四天
测试类继承Thread类
Thread类的一些方法:
- public final String getName() 获取线程名称
- public final void setName(String name) 指定线程名称
- public static Thread currentThread() 获取当前线程对象
将类声明为Thread的子类。该子类重写Thread类的run方法。创建对象,开启线程。 开启线程的步骤:
- 指定线程执行目标:定义一个Thread类的子类,重写run方法,将相关逻辑实现
- public void run() 线程要执行的业务逻辑方法,相当于该线程的"main方法"
- 创建自定义的线程子类对象
- 开启线程动作 public void start() 使该线程开始执行
- 重写run方法,我们的逻辑代码存放于run方法中
- 不会主动执行run方法
- 调用线程类的启动方法,由这个方法来调用run方法
需要进行的操作写在run方法里,通过在测试类中的start方法进行间接调用
实现Runnable接口创建线程
创建线程的另一种方法是声明实现 Runnable 接口的类,该类然后实现 run 方法。然后创建Runnable的实现类对象,传入到某个线程的构造方法中,开启线程。
查看Runnable接口说明文档:Runnable接口用来指定每个线程要执行的任务。包含了一个 run 的无参数抽象方法,需要由接口实现类重写该方法。 开启线程的步骤:
- 指定线程执行目标:定义Runnable线程执行目标实现类,重写run方法,指定目标逻辑
- 通过指定线程执行目标的构造方法创建线程对象 public Thread(Runnable target)
- 创建线程执行目标对象
- 通过线程执行目标创建线程对象
- 开启线程动作 (start开启线程)
Runnable的run方法功能就是去写run方法中的逻辑代码
通过实现Runable接口方法的子类传入到Thread的构造方法中实现
package lesson14;
//T3不是线程,只是把线程中的业务代码在run方法中编写
public class T3 implements Runnable{
private String threadname;
public T3(String threadname) {
super();
this.threadname = threadname;
}
public T3() {
super();
}
public String getThreadname() {
return threadname;
}
public void setThreadname(String threadname) {
this.threadname = threadname;
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 500; i++) {
System.out.println(threadname+i);
}
}
}
public static void main(String[] args) {
T3 t=new T3();
T3 tx=new T3();
//创建一个线程
Thread t1=new Thread(t);
//创建第二个线程
Thread t2=new Thread(tx);
t.setThreadname(t1.getName());
tx.setThreadname(t2.getName());
t1.start();
t2.start();
}
两种创建方式有什么区别
Thread实现线程功能 继承Thread类 重写run方法
问题: 每个线程对应一个类 run方法中的相同代码较多,出现代码冗余
自定义类实现Runnable接口 把自定义类放入Thread类中作为构造方法的参数 (相当于重写Runnable方法) 重复代码只需要写一次 实现比上一种方法麻烦一些
继承Thread类后,数据不能共享! 实现Runnable接口后,数据可以共享也可以不实现共享;
在不共享数据和代码的情况下,可以直接继承Thread类
使用匿名内部类创建线程对象
- 创建Thread类
- 调用start()
- 重写run方法; 不但实现了接口/继承了父类,还实现了run方法重写
Thread匿名内部类
new Thread(){
public void run(){
//代码
}
}.start();
Runnable接口
new Thread(new Runnable(){
public void run(){
//代码
}
}){}.start();
多线程买票案例
有可能出现重复购票,由于资源处于临界
线程的生命周期
- 创建线程处于新建状态
- 执行start方法,启动状态
- run方法执行完成,进入死亡状态
- 调用sleep(等待的毫秒数)可以使线程进入等待,静态方法直接调用,Thread.sleep(); join()等待线程执行完成