boolean isAlive() | 测试线程是否处于活动状态 |
setPriority(int newPriority) | 更改线程优先级 |
static void sleep(long millis) | 让指定线程休眠指定的毫秒数 |
void join() | 线程插队 强制执行 |
static void yield() | 线程礼让 |
void interrupt() | 线程中断 |
wait() | 线程等待 |
notify() notifyAll() | 线程唤醒 |
1.Thread.sleep(时间) 指定当前线程阻塞的 毫秒数;
2.线程休眠存在异常,所以要捕获异常
3.sleep时间达到后线程进入就绪状态
4.每个对象都有一个锁,sleep不会释放锁,但会让出CPU
1. Thred.yield() 让当前执行的线程暂停,但不阻塞,
2.使线程从运行状态转为就绪状态
3.让CPU重新调度,礼让不一定成功。
4.yield会使当前线程重回到可执行状态,等待cpu的调度,不释放锁
1.Thread.jion() 调用此方法的线程强制执行,把调用此方法的线程运行结束后,在运行其他线程
2.当前线程调用 某线程.join()时会使当前线程等待某线程执行完毕再结束,底层调用了wait,释放锁
测试代码
package com.example.demo.therad;
public class JionDemo implements Runnable{
public void run() {
for(int i=0;i<20;i++) {
System.out.println("VIP:"+i);
}
System.out.println("VIP运行完了");
}
}
public static void main(String[] args) throws Exception{
JionDemo jionDemo=new JionDemo();
Thread thread=new Thread(jionDemo);
thread.start();
for(int i=0;i<=30;i++) {
if (i==10) {
thread.join();
}
System.out.println("普通客户运行:"+i);
}
结果
普通客户运行:0
VIP:0
普通客户运行:1
VIP:1
普通客户运行:2
普通客户运行:3
普通客户运行:4
普通客户运行:5
普通客户运行:6
VIP:2
普通客户运行:7
普通客户运行:8
普通客户运行:9
VIP:3
VIP:4
VIP:5
VIP:6
VIP:7
VIP:8
VIP:9
VIP:10
VIP:11
VIP:12
VIP:13
VIP:14
VIP:15
VIP:16
VIP:17
VIP:18
VIP:19
VIP运行完了
普通客户运行:10
普通客户运行:11
普通客户运行:12
普通客户运行:13
普通客户运行:14
普通客户运行:15
普通客户运行:16
普通客户运行:17
普通客户运行:18
普通客户运行:19
普通客户运行:20
普通客户运行:21
普通客户运行:22
普通客户运行:23
普通客户运行:24
普通客户运行:25
普通客户运行:26
普通客户运行:27
普通客户运行:28
普通客户运行:29
普通客户运行:30
1.wait()方法 使线程一直等待,直到有其他线程通知唤醒
2.线程等待会释放锁
3.唤醒等待线程 用notify(唤醒一个等待线程)notifyAll 唤醒所有的等待线程
4,使用wait(long m)方法 wait方法如果在毫秒值结束之后 还没有被notify唤醒 就会自动醒来 线程睡醒进入到Runanle/Blocked状态
5.wait与notify、notifyAll必须配合synchronized使用,因为调用之前必须持有锁,wait会立即释放锁,notify则是同步块执行完了才释放
6.唤醒当前对象锁的等待线程使用notify或notifyAll方法,也必须拥有相同的对象锁,否则也会抛出IllegalMonitorStateException异常。
线程的等待还可以使用
ReenTrantLock
Condtion condition=lock.newCondition
await() 等待
singal() 唤醒
Condition类提供,而Condition对象由new ReentLock().newCondition()获得,与wait和notify相同,因为使用Lock锁后无法使用wait方法
案例生产者 消费者
package com.example.demo.therad;
//生产者
public class Provider implements Runnable {
private ChickenContainer chickenContainer;
public Provider(ChickenContainer chickenContainer) {
this.chickenContainer=chickenContainer;
}
public void run() {
for (int i = 1; i <=20; i++) {
chickenContainer.push(new Chick(i));
}
}
}
package com.example.demo.therad;
//消费者
public class Consumer implements Runnable {
private ChickenContainer chickenContainer;
public Consumer(ChickenContainer chickenContainer) {
this.chickenContainer=chickenContainer;
}
public void run() {
for (int i = 1; i <=20; i++) {
chickenContainer.pop(new Chick(i));
}
}
}
package com.example.demo.therad;
//生产者 消费者 容器
import java.util.LinkedList;
public class ChickenContainer {
LinkedList list=new LinkedList();
private int num = 10;//容器大小
//生产者生产
public synchronized void push(Chick chick) {
if (list.size()== num) {
//如果容器已满 生产者等待
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//通知消费者 消费
System.out.println("生产者生产了第:"+chick.getId()+"只");
list.add(chick);
this.notifyAll();
}
//消费者 消费
public synchronized void pop(Chick chick) {
if (list.isEmpty()) {
//容器为空 消费者等待
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//通知 生产者 生产
System.out.println("消费者消费了第:"+chick.getId()+"只");
list.remove(0);
this.notifyAll();
}
}
测试
public static void main(String[] args) throws Exception{
ChickenContainer chickenContainer=new ChickenContainer();
Provider provider=new Provider(chickenContainer);
Consumer consumer=new Consumer(chickenContainer);
Thread proThread=new Thread(provider);
Thread conThread=new Thread(consumer);
proThread.start();
conThread.start();
}
运行结果
生产者生产了第:1只
生产者生产了第:2只
生产者生产了第:3只
生产者生产了第:4只
生产者生产了第:5只
生产者生产了第:6只
生产者生产了第:7只
生产者生产了第:8只
生产者生产了第:9只
生产者生产了第:10只
消费者消费了第:1只
消费者消费了第:2只
消费者消费了第:3只
消费者消费了第:4只
消费者消费了第:5只
消费者消费了第:6只
消费者消费了第:7只
消费者消费了第:8只
消费者消费了第:9只
消费者消费了第:10只
生产者生产了第:11只
生产者生产了第:12只
生产者生产了第:13只
生产者生产了第:14只
生产者生产了第:15只
生产者生产了第:16只
生产者生产了第:17只
生产者生产了第:18只
生产者生产了第:19只
生产者生产了第:20只
消费者消费了第:11只
消费者消费了第:12只
消费者消费了第:13只
消费者消费了第:14只
消费者消费了第:15只
消费者消费了第:16只
消费者消费了第:17只
消费者消费了第:18只
消费者消费了第:19只
消费者消费了第:20只
public class ThreadSafe extends Thread {
public void run() {
while (!isInterrupted()){ //非阻塞过程中通过判断中断标志来退出
try{
Thread.sleep(5*1000);//阻塞过程捕获中断异常来退出
}catch(InterruptedException e){
e.printStackTrace();
break;//捕获到异常之后,执行 break 跳出循环
}
}
}
}
使用 isInterrupted()方法
class TestThread extends Thread{
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + "正在打印 i = " + i);
}
}
}
public class TestInterrupted {
public static void main(String[] args) {
TestThread mt = new TestThread();
mt.start();
mt.interrupt();
System.out.println("第一次调用isInterrupted()方法,值为:" + mt.isInterrupted());
System.out.println("第二次调用isInterrupted()方法,值为:" + mt.isInterrupted());
System.out.println("thread是否存活:" + mt.isAlive());
}
}
isInterrupted()方法:测试线程是否被中断,不会清除中断状态。
使用interrupted()方法
public class TestInterrupted {
public static void main(String[] args) {
Thread.currentThread().interrupt();
System.out.println("第一次调用isInterrupted()方法,值为:" + Thread.currentThread().isInterrupted());
System.out.println("调用interrupted()方法,值为:" + Thread.currentThread().interrupted());
System.out.println("调用interrupted()方法,值为:" +Thread.currentThread().interrupted());
}
}
结果可以看到第二次调用interrupted()方法返回false
线程状态。
线程可以处于以下状态之一:
NEW
尚未启动的线程处于此状态。
RUNNABLE
在Java虚拟机中执行的线程处于此状态。
BLOCKED
被阻塞等待监视器锁定的线程处于此状态。
WAITING
正在等待另一个线程执行特定动作的线程处于此状态。
TIMED_WAITING
正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。
TERMINATED
已退出的线程处于此状态。