线程控制方法

线程的常用方法
Thread t = new Thread(); 

1. 启动线程 shart()

t.stat();	//启动线程

2. 停止线程

注意:不建议使用stop()和destory()方法(已过时),调用其可能会产生不可预料的结果;
线程停止有两种情况:

  • 线程体执行结束时线程结束;

  • 人为干预,典型做法是提供一个boolean类型的终止变量,当这个变量置为false,终止线程的运行;

例如:

class Terminal implements Runnable {
    //1、加入标识,标记线程体是否可以运行
    private boolean flag = true;
    private String name;
    public Terminal(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        int i = 0;
        //2、关联标识,true运行,false停止运行
        while (flag) {
            System.out.println(name + "--->" + i++);
        }
    }
	//提供修改标识的方法
    public void terminate() {
        this.flag = false;
    }
}
public class TestTerminal {
    public static void main(String[] args) {
        Terminal terminal = new Terminal("a");
        new Thread(terminal).start();
        for (int i = 0;i < 10;i++) {
            if (i == 8) {
                terminal.terminate();
                System.out.println("terminal 终止"); //终止线程terminal
            }
            System.out.println(Thread.currentThread().getName() + "--->" + i);
        }
    }
}

运行结果:在main函数里,当i==8时终止了子线程
在这里插入图片描述

3. 休眠线程sleep()

这里要注意的有:

  • 该方法在哪个线程体中,当前线程类对象阻塞;
  • sleep(millis)指定当前线程阻塞的毫秒数;
  • 存在异常InerruptedException,因为run()无法抛出异常所以只能用try catch捕获异常;
  • sleep时间达到后线程进入就绪状态
  • 每一个对象都会有一个锁,而sleep不会释放锁;

sleep()的应用:

  • 可以模拟网络延时
  • 倒计时

例1:模拟龟兔赛跑,让兔子每走十步休眠100ms;

public class TestRacer implements Runnable{
    private static String winner; // 胜利者
    @Override
    public void run() {
        for (int steps = 1; steps <= 100; steps++) {
            //模拟休息
            if (Thread.currentThread().getName().equals("rabbit") && steps % 10 == 0) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + "-->" + steps);
            // 比赛是否结束
            boolean flag = gameOver(steps);
            if (flag) {
                break;
            }
        }
    }
    private boolean gameOver(int steps) {
        if (winner != null) {
            return true;
        } else if (steps == 100) {
                winner = Thread.currentThread().getName();
                System.out.println("winner -->" + winner);
                return true;
        }
        return false;
    }

    public static void main(String[] args) {
        TestRacer racer = new TestRacer();
        new Thread(racer,"tortoise").start();
        new Thread(racer,"rabbit").start();
    }
}

例2:模拟网上购票

class Sell implements Runnable{
    private int ticketNum = 0;
    @Override
    public void run() {
        while (true) {
            if (ticketNum > 20) {
                break;
            }
            //模拟延时
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ticketNum++);
        }
    }
}

例3:模拟倒计时

public class TestBlockedSleep01 {
    public static void main(String[] args) throws InterruptedException {
        Date endTime = new Date(System.currentTimeMillis() + 1000*10); //分:秒
        long end = endTime.getTime();
        while (true) {
            System.out.println(new SimpleDateFormat("mm:ss").format(endTime));
            Thread.sleep(1000);
            endTime = new Date(endTime.getTime() - 1000);

            if (end - 10000 > endTime.getTime()) {
                break; //十秒后跳出循环,倒计时结束
            }
        }
    }
    public static void test() throws InterruptedException {
        int num = 10;
        while (true) {
            Thread.sleep(1000);
            System.out.println(num--);
        }
    }
}

运行结果:
在这里插入图片描述
4. 线程让步yield()

  让正在执行的线程停止或让步,让给优先级较高的线程获取CPU的执行权,不一定会让出CPU执行权,取决于操作系统,若等待的线程优先级较低或者当前只有一个线程在执行时,那么当前线程又会立即获取到CPU的执行权

  • 礼让线程,让当前正在执行线程暂停
  • 不是阻塞线程,而是线程从运行状态转入就绪状态,让CPU重新调度

例1:

class Yield implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "start");
        Thread.yield(); //线程让步
        System.out.println(Thread.currentThread().getName() + "end");
    }
}
public class TestYield {
    public static void main(String[] args) {
        Yield m = new Yield();
        new Thread(m,"a").start();
        new Thread(m,"b").start();
    }
}

一次运行结果:让步成功
在这里插入图片描述
例2:主线程中i为2的倍数时,主线程调用yield();

ublic class TestYield02 {
    public static void main(String[] args) {
        new Thread(() -> {
            for (int i = 0;i < 5;i++) {
                System.out.println("lambda" + i);
            }
        }).start();
        for (int i = 0;i < 5;i++) {
            if (i % 2 == 0) {
                Thread.yield();
            }
            System.out.println("main" + i);
        }
    }
}

5. 线程加入join()

  • 合并线程,其他线程阻塞待此线程执行完成后,再执行其他线程;

例:

public class TestJion {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            for (int i = 0;i < 10;i++) {
                System.out.println("lambda" + i);
            }
        });
        t.start();
        for (int i = 0;i < 10;i++) {
            if (i == 4) {
                t.join();//插队  main主线程被阻塞
            }
            System.out.println("main" + i);
        }
    }
}

结果:主线程阻塞后,子线程结束之后才得以继续执行;
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值