线程 停止、休眠、礼让、强制执行
线程停止:
/**
* 停止线程不推荐使用JDK提供的stop或者destroy(已废弃)
* 推荐线程自己停下来
* 建议使用一个标志位进行终止变量,当flag=false,则线程终止运行
*/
通过标志位来终止变量进而终止线程,具体代码实现如下:
public class TestStop implements Runnable {
//设置一个标志位
boolean flag = true;
@Override
public void run() {
int i = 0;
while (flag){
System.out.println("run...Thread"+i++);
}
}
//设置一个公开的方法转换标志位,停止线程
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("线程该停止了");
}
}
}
}
当主线程执行到900的时候,调用自定义的stop方法停止了子线程
休眠Sleep
/**
* sleep(时间)指定当前线程阻塞的毫秒数
* Sleep存在异常InterruptedException
* sleep时间到达之后线程进入就绪状态;
* sleep可以模拟网络延迟与倒计时等
* !!!每个对象都有一个锁,sleep不会释放锁
*/
核心代码:
Thread.sleep(1000);
详细代码:
//模拟网络延迟:放大问题的发生性
public class TestSleep implements Runnable {
//票数
private int tickName = 10;
@Override
public void run() {
while (true){
if (tickName<=0){
break;
}
//模拟延时
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"拿到了第"+tickName--+"张票");
}
}
public static void main(String[] args) {
TestSleep testSleep = new TestSleep();
new Thread(testSleep,"yuan").start();
new Thread(testSleep,"hui").start();
new Thread(testSleep,"黄牛").start();
}
}
注意:
1.如果上述代码没有模拟延时,由于CPU执行效率很快,yuan会将所有票拿到
2.进行模拟延时之后,因为是多个线程同时调用同一个资源,线程是不安全的,数据紊乱,可能出现-1张票,或者个线程对象都抢同一张票
礼让 yield
/**
* 礼让线程,让当前正在执行的线程暂停,但不阻塞
* 将线程从运行状态转为就绪状态
* 让CPU重新调度,礼让不一定成功,看CPU心情
*/
核心代码:
Thread.yield();//礼让
详细代码:
public class TestYield {
public static void main(String[] args) {
MyYield myYield = new MyYield();
new Thread(myYield,"a").start();
new Thread(myYield,"b").start();
}
}
class MyYield implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"开始执行");
Thread.yield();//礼让
System.out.println(Thread.currentThread().getName()+"停止执行");
}
}
注意:礼让将线程从运行状态转为就绪状态,让CPU重新调度,礼让不一定成功,看CPU心情
结果1:(说明礼让成功,a开始执行后礼让b开始执行)
a开始执行
b开始执行
a停止执行
b停止执行
结果2:(说明礼让失败,a线程停止执行后才b才开始执行
a开始执行
a停止执行
b开始执行
b停止执行
强制执行 join
/**
* Join合并线程,待此线程执行完毕之后,再执行其他线程,其他线程阻塞
* 可以想象成插队
*/
核心代码:
thread.join();//插队
详细代码:
public class TestJoin implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("线程VIP来了"+i);
}
}
public static void main(String[] args) throws InterruptedException {
TestJoin testJoin = new TestJoin();
Thread thread = new Thread(testJoin);
thread.start();
for (int i = 0; i < 10; i++) {
System.out.println("Main"+i);
if (i==3){
thread.join();//插队
}
}
}
}
注意:
调用join后,待此线程执行完毕才会执行其他线程,其他线程为阻塞状态