一、线程使用
创建线程有两种方法。一是实现Runnable接口,另外一个是继承Thread类,Thread实现了Runnable接口。
继承Thread类:
public class Home {
public static void main(String[] args) {
final Cat cat = new Cat();
cat.start();
}
}
class Cat extends Thread {
@Override
public void run() {
while (true) {
System.out.println("线程代码");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
- 继承Thread类
- 重写run方法,在run方法里写线程代码
- 主方法调用start方法,底层jvm是调用了start0()这个方法。
实现Runnable接口:
public class Home {
public static void main(String[] args) {
final Cat cat = new Cat();
final Thread thread = new Thread(cat);
thread.start();
}
}
class Cat implements Runnable {
@Override
public void run() {
while (true) {
System.out.println("线程代码");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
- 实现Runnable 接口
- 重写run方法
- 主方法中先创建Thread实例,把实现了Runnable 接口的类放入,再调用start方法
二、停止线程
public class Home {
public static void main(String[] args) {
final Cat cat = new Cat();
final Thread thread = new Thread(cat);
thread.start();
cat.setLoop(false); //启动线程时,主方法线程是并行的,所以会立刻关闭线程
}
}
class Cat implements Runnable {
private boolean loop = true;
public void setLoop(boolean loop) {
this.loop = loop;
}
@Override
public void run() {
while (loop) {
System.out.println("线程代码");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
- 在实现Runnable类里设置一个开关变量,并暴露一个set方法。
- 主方法调用set方法来控制线程开关。
三、线程方法
- start() 启动线程
- setPriority 更改线程优先级
- getPriority 获取线程优先级
- sleep 设置毫秒数指定让线程休眠
- interrupt 中断线程,是中断正在休眠的线程让它立刻醒来
- yield 线程礼让,让出cpu让其他线程先走,但是不一定成功
- join 线程插队,让插队的线程执行完所有,才会继续走
- wait 调用该方法后会将当前线程阻塞
四、守护线程
把一个线程设置为守护线程后,当所有用户线程结束,守护线程也自动结束。
public class Home {
public static void main(String[] args) {
final Cat cat = new Cat();
final Thread thread = new Thread(cat);
thread.setDaemon(true); // 设置为守护线程
thread.start();
}
}
class Cat implements Runnable {
@Override
public void run() {
while (true) {
System.out.println("线程代码");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
- 设置完守护线程后,主线程执行完毕结束后,用户线程也就立刻关闭了。
五、线程声明周期
![](https://img.haomeiwen.com/i67572/7d3e3f43e4237922.png)
java 线程类Thread的STATE枚举包括了6个状态:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED;
-
NEW 至今尚未启动的线程的状态。
-
RUNNABLE 可运行线程的线程状态。处于可运行状态的某一线程正在 Java 虚拟机中运行,但它可能正在等待操作系统中的其他资源,比如处理器。
-
BLOCKED 受阻塞并且正在等待监视器锁的某一线程的线程状态。处于受阻塞状态的某一线程正在等待监视器锁,以便进入一个同步的块/方法,或者在调用 Object.wait 之后再次进入同步的块/方法。
-
WAITING 某一等待线程的线程状态。某一线程因为调用下列方法之一而处于等待状态:
某一等待线程的线程状态。某一线程因为调用下列方法之一而处于等待状态:
- 不带超时值的 Object.wait
- 不带超时值的 Thread.join
LockSupport.park
处于等待状态的线程正等待另一个线程,以执行特定操作。 例如,已经在某一对象上调用了 Object.wait() 的线程正等待另一个线程,以便在该对象上调用 Object.notify() 或 Object.notifyAll()。已经调用了 Thread.join() 的线程正在等待指定线程终止。
- TIMED_WAITING具有指定等待时间的某一等待线程的线程状态。某一线程因为调用以下带有指定正等待时间的方法之一而处于定时等待状态:
Thread.sleep
带有超时值的 Object.wait
带有超时值的 Thread.join
LockSupport.parkNanos
LockSupport.parkUntil
- TERMINATED 已终止线程的线程状态。线程已经结束执行。
六、线程同步
不允许多个线程同时操作某个数据时,使用Synchronized关键字。
//方法名前加上Synchronized关键字
@Override
public synchronized void run() {
while (true) {
System.out.println("线程代码");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// Synchronized代码块
public void eat(){
synchronized (this){
System.out.println("吃");
}
}
- 同步方法如果不是静态的,默认锁对象统一为this
- 如果方法是静态的,锁对象为当前类.class
网友评论