1.通过继承Thread(线程)类本身。
创建线程时继承Thread类并重写Thread类的run()方法。Thread类的run()是线程要执行操作任务的方法,所以线程要执行的操作代码都需要写在run()方法中,并通过调用start()方法来启动线程。
使用Thread类创建线程的优点是简单明了;同时最大的缺点是:如果定义的类已经继承了其他类则无法再继续继承Thread类。因此Thread类适用于单重继承的情况。
2. 使用Runnable接口创建线程
使用Runnable接口实现线程的代码块结构其实与使用Thread类创建线程的代码块结构相似。一个类可以通过实现Runnable接口并实现其run()方法完成线程对象的所有活动,已经实现的的run()方法称为该对象的线程体。任何实现Runnable接口的对象都可以作为一个线程的目标对象。
package cn.myThread;
//通过定义MyThread类实现Runnable接口实现线程应用
public class MyThread implements Runnable {
private int count = 0;
public void run() {
while (count < 100) {
count++;
System.out.println("count的值是:" + count);
}
}
public static void main(String[] args) {
//接口线程创建对象最后还是要与线程Thread本身结合创建线程对象
MyThread mt = new MyThread();
Thread thread = new Thread(mt);
// Thread thread=new Thread(new MyThread());
thread.start();
}
}
使用Runnable接口实现线程兼容了Thread类实现接口的缺陷。即实现了Runnable接口的方式,当一个线程继承了另一个;类时,就只能用实现Runnable接口的方法来创建线程,而且这种方式还可以使多个线程之间使用同一个Runnable对象。
3. 线程的状态
线程的生命周期可以分成5个阶段,即5种状态,分别是创建状态、就绪状态、运行状态、阻塞状态、死亡状态。(也有说4个阶段,即:新生状态、可运行状态、阻塞状态、死亡状态)
从创建类,用什么方式实现线程以及new一个线程对象,调用start()方法,线程都是从创建状态到就绪状态。在调用start()方法后启动线程,系统为该线程分配除CPU外的所需资源,这个线程就有了运行机会,在得到CPU资源后才转为运行状态,再该状态中,该线程对象可能正在运行,也可能尚未运行。因为一个CPU机器任何时刻只能有一个处于可运行状态的线程占用处理机,获得CPU资源,此时系统真正运行线程的run()方法。
4.线程调度
4.1设置线程的优先级
线程对象.setPriority(1-10);
优先级等级从1-10 1表示最低级;10表示最高级;5是默认级别
每一个优先级对应一个Thread类的公用静态常量:
Public static final int MIN_PRIORITY=1;
Public static final int MAX_PRIORITY=10;
Public static final int NORM_PRIORITY=5;
4.2实现线程调度的方法
(1)join()方法:使当前线程(指join方法被放入的那个类的线程,比如在主线程里,被阻塞的是主线程,等子线程执行完后再执行主线程)暂停执行,等待调用该方法的线程(被调用的线程)结束后再继续执行本线程。
三种重载形式:
Public final void join()
Public final void join(long mills)
Public final void join(long mills,int nanos)
(2)sleep()休眠方法:会让当前线程睡眠(停止执行)millis毫秒,线程由运行中的状态进入不可运行状态,睡眠时间过后线程会再次进入可运行状态。
使用方法:对象线程.sleep(long mills);
在run()方法中使用sleep()方法阻塞线程。
package cn.myThread;
public class Wait {
public static void bySec(long s) {
for (int i = 0; i < s; i++) {
System.out.println(i + 1 + "秒");
try {
Thread.sleep(1000); //睡眠1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
System.out.println("Wait"); //提示等待
Wait.bySec(5); //让主线程等待5秒再执行
System.out.println("start"); //提示恢复执行
}
}
运行结果:
Wait
1秒
2秒
3秒
4秒
5秒
start
(3)yield()礼让方法:让当前线程暂停执行,允许其它线程执行,但该线程仍处于可运行状态,并不变为阻塞状态。此时,系统选则其他相同或更高优先级线程执行,若无其他相同或更高优先级线程,则继续执行该线程。
语法格式:【public static void yield()】
在run()方法中使用yield()方法暂停线程
(4)区别
Sleep()方法与yield()方法的区别
Sleep()方法 |
yield()方法 |
使当前线程进入被阻塞状态 |
将当前线程转入暂停执行的状态 |
即使没有其他等待运行的线程,当前线程也会等待指定的时间 |
如果没有其他等待执行的线程,当前线程会马上恢复执行 |
其他等待执行的线程的机会是均等的 |
会运行优先级相同或更高的线程 |