我们先看线程状态图
线程方法
方法 | 说明 |
---|---|
setPriority(int n) | 更改线程优先级 |
sleep(long millis) | 在指定毫秒内让当前正在执行的线程休眠 |
void join() | 等待当前线程终止 |
static void yield() | 暂停当前正在执行的对象,并执行其他线程 |
boolean isAlive() | 测试线程是否处于活动状态 |
wait() | 线程等待,使线程由运行态进入阻塞态 |
1.线程终止:我们这里线程终止最后不用系统给的方法,通过使用标识位flag==flase来判断终止线程。
/*
* 测试stop
* */
public class TestStop implements Runnable{
//1.设置一个标识位
private boolean flag =true;
@Override
public void run() {
int i=0;
while (flag){
System.out.println("run...Thread"+i++);
}
}
//2.设置一个公开方法停止线程,转换标志位
public void stop(){
this.flag=false;
}
public static void main(String[] args) {
TestStop testStop= new TestStop();
new Thread(testStop).start();
for (int i = 0; i <1000 ; i++) {
System.out.println("main"+i);
if (i == 900) {
//调用stop方法切换标识位,让线程停止
testStop.stop();
System.out.println("该线程该停止了!");
}
}
}
}
2.线程休眠sleep()
线程暂停yield()
线程暂停会让cpu重新调度,但是不一样会成功
package com.cui.thread01;
public class TestYield {
public static void main(String[] args) {
MyYield m=new MyYield();
new Thread(m,"a").start();
new Thread(m,"b").start();
}
}
class MyYield implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程开始执行");
Thread.yield();
System.out.println(Thread.currentThread().getName()+"线程停止执行");
}
}
成功:
失败:
join()方法 就是线程插队
待此线程执行完成后,在执行其他线程,其他线程阻塞
package com.cui.thread01;
public class TestJoin implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("线程vip has come on"+i);
}
}
public static void main(String[] args) throws InterruptedException {
TestJoin testJoin = new TestJoin();
new Thread(testJoin).start();
//主线程
for (int i = 0; i < 1000; i++) {
if (i == 200) {
//插队
new Thread(testJoin).join();
}
System.out.println("main"+i);
}
}
}
线程等待wait()
这里线程等待的我们用一个生产者消费者问题(这里用到TimeUnit延时执行以及lambda表达式)
import java.util.concurrent.TimeUnit;
//生产者消费者问题
//管程法---利用缓冲区
//生产者类+消费者类+产品类+缓冲区类
public class TestPc {
public static void main(String[] args) {
//不允许用 P 和 C 用lamda表达式实现
ConponentMiddle conponentMiddle = new ConponentMiddle();
new Thread(()->{
for (int i = 0; i < 11; i++) {
try {
conponentMiddle.push(new Product(i));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"生产者").start();
new Thread(()->{
for (int i = 0; i < 11; i++) {
conponentMiddle.pop();
}
},"消费者").start();
}
}
//缓冲区
class ConponentMiddle {
//需要一个容器,放产品
Product[] products = new Product[10];
//容器计数器
int count = 0;
//生产者生产
public synchronized void push(Product product) throws InterruptedException {
//判断容器是否满的,如果满了,就需要等待消费者消费
if (count == products.length-1) {
//通知消费者消费,生产者等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果容器没有满,生产者就要放入产品
TimeUnit.SECONDS.sleep(1);
products[count] = product;
count++;
System.out.println(Thread.currentThread().getName()+","+product.id);
notify();
//可以通知消费者消费了。
}
//消费者消费
public synchronized Product pop() {
//判断是否为空
if (count == 0) {
//消费者等待,生产者生产
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果有产品,消费者就消费
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
count--;
Product product = products[count];
System.out.println(Thread.currentThread().getName()+product.id);
//消费结束,等待生产者生产
return product;
}
}
//产品类
class Product {
int id;
public Product(int id) {
this.id = id;
}
}
最后,我们总结一下sleep和wait的区别
sleep | wait |
---|---|
继承自Thread类 | 继承自Object类 |
适用在所有地方 | 只能在同步代码块 |
不会释放锁 | 会释放锁资源 |