线程终止、暂停、礼让、插队
线程终止
code:
/**
* 终止线程
* 1. 线程执行完毕-->次数
* 2. 外部干涉--->加入标识
* 不要使用stop() 或 destory()来终止线程
* @author dxt
*
*/
public class TerminateThread implements Runnable{
//加入标识
private boolean flag = true;
/**
* 实现run()方法,在run()中关联标识flag
*/
public void run(){
int i = 0;
while(flag){
System.out.println(i + "--run()");
i++;
}
}
/**
* 通过改变标识来终止线程
*/
public void terminate(){
this.flag = false;
}
public static void main(String[] args){
TerminateThread tt = new TerminateThread();
Thread t = new Thread(tt);
t.start();
for(int i=0; i<20; i++){
if(i == 15){ //外部执行15次循环时,终止线程
tt.terminate();
}
System.out.println(i + "---main()");
}
}
}
线程暂停(sleep)
- sleep(时间)指定当前线程阻塞的毫秒数
- sleep存在异常InterruptedException
- sleep执行后进入阻塞状态,时间达到后线程进入就绪状态
- sleep可以模拟网络延迟、倒计时等
- 每一个对象都有一个锁,sleep不会释放锁
code1:
/**
* sleep()模拟网络延迟
* @author dxt
*
*/
public class BlockedSleep implements Runnable{
private int ticketNums = 99; //票数
/**
* 实现run()方法
* run()方法不要抛出异常,而是使用try--catch处理异常
*/
public void run(){
while(true){
if(ticketNums < 0){
break;
}
try{
Thread.sleep(200); //模拟网络延迟,同一时间会有多人访问第i张票
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +"---" + ticketNums--);
}
}
public static void main(String[] args){
BlockedSleep bs = new BlockedSleep();
new Thread(bs, "dxt1").start();
new Thread(bs, "dxt2").start();
new Thread(bs, "dxt3").start();
}
}
code2(使用sleep()进行倒数操作):
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 利用sleep()来进行倒计时
* @author dxt
*
*/
public class BlockedSleep02 {
/**
* 倒数数字,1秒一个数字
* @param time
*/
public void lastNum(int seconds){
int num = seconds;
while(num > 0){
try {
Thread.sleep(1000); //sleep()是静态方法
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(num--);
}
}
/**
* 从当前时间 数到 num秒后,
* 显然程序存在一些问题:比如sleep(1000)是一秒,但循环执行也会使用时间
* @param num
* @throws InterruptedException
*/
public void lastTime(int num) throws InterruptedException{
Date endTime = new Date(System.currentTimeMillis() + num*1000);
long end = endTime.getTime();
Date nowTime = new Date();
while(true){
System.out.println(new SimpleDateFormat("mm:ss").format(nowTime));
Thread.sleep(1000);
nowTime = new Date();
if(end < nowTime.getTime()){
break;
}
}
}
public static void main(String[] args) throws InterruptedException{
BlockedSleep02 bs2 = new BlockedSleep02();
//bs2.lastNum(10);
bs2.lastTime(10);
}
}
线程礼让(yield)
- yield(): 礼让线程,让当前执行的线程暂停。
- 不进入阻塞状态,而是将线程从运行状态转入就绪状态。
- 让CPU调度器重新调度。
code:
/**
* 测试yield()方法
* yield()使线程进入就绪状态
* @author dxt
*
*/
public class YieldDemo01 {
public static void main(String[] args){
MyYield m = new MyYield();
//建立两个线程
new Thread(m, "aa").start();
new Thread(m, "bb").start();
}
}
class MyYield implements Runnable{
/**
* 重写run方法
*/
public void run(){
System.out.println(Thread.currentThread().getName() + "--->start");
Thread.yield(); //yield为静态方法;可能会使CPU调别的线程,也可能会使CPU调自己,因为将自己加入了就绪队列
System.out.println(Thread.currentThread().getName() + "--->end");
}
}
线程插队(join)
- join合并线程,待此线程执行完后,再执行其他线程。
- join()是成员方法,写在那个线程体中,那个线程就被阻塞了。
code:
/**
* 测试join方法
* @author dxt
*
*/
public class BlockedJoin01 implements Runnable{
/**
* 实现run()
*/
public void run(){
for(int i=0; i<20; i++){
System.out.println("另一条线程啊--->" + i);
}
}
public static void main(String[] args) throws InterruptedException{
Thread t = new Thread(new BlockedJoin01());
t.start(); //建立线程
for(int i=0; i<30; i++){
if(i == 10){
t.join(); //将在此阻塞main()所在线程,即等run()执行完后,在执行接下来的循环
}
System.out.println("main--->" + i);
}
}
}