多线程(三)—— 方法篇

线程的方法

1.1 启动一个线程

start() 与 run()

public class scence {

    private static long fib(int n){
        if(n < 2){
            return n;
        } else {
            return fib(n-1) + fib(n-2);
        }
    }

    private static class MyThread extends Thread{
        private int n;
        public MyThread(int n){
            this.n = n;
        }

        @Override
        public void run() {
            long result = fib(n);
            System.out.println(Thread.currentThread().getName());

        }
    }

    public static void main(String[] args) {
        int n = 6;
        while(n > 0){
            //来了客人,就找人来干活,启动的线程在完成真正的计算工作
            Thread thread1 = new MyThread(n);
            thread1.start();
            long result = fib(n);
            System.out.println(Thread.currentThread().getName());
            n--;
        }
    }
}

运行结果;
在这里插入图片描述

  • 调用 .start() 方法, 启动一个线程,线程之间是没有顺序的,是按CPU分配的时间片来回切换的。
public class scence {

    private static long fib(int n){
        if(n < 2){
            return n;
        } else {
            return fib(n-1) + fib(n-2);
        }
    }

    private static class MyThread extends Thread{
        private int n;
        public MyThread(int n){
            this.n = n;
        }

        @Override
        public void run() {
            long result = fib(n);
            System.out.println(Thread.currentThread().getName());

        }
    }

    public static void main(String[] args) {
        int n = 6;
        while(n > 0){
            //来了客人,就找人来干活,启动的线程在完成真正的计算工作
            Thread thread1 = new MyThread(n);
            thread1.run();
            long result = fib(n);
            System.out.println(Thread.currentThread().getName());
            n--;
        }
    }
}

执行结果:
在这里插入图片描述

  • 调用线程的run方法,就是普通的方法调用,虽然将代码封装到两个线程体中,但直接调用run()方法会导致线程未启动,主线程在干活。
    run()方法用于封装线程的代码,具体要启动一个线程来运行线程体中的代码还是通过start()方法来实现,调用run()方法就是一种顺序编程不是并发编程。

1.2 中止一个线程

sleep() 和 interrupt()

 thread.sleep(指定时间,单位为毫秒);
 thread.interrupt();

sleep(long millis): 睡眠指定时间,程序暂停运行,睡眠期间会让出CPU的执行权,去执行其它线程,同时CPU也会监视睡眠的时间,一旦睡眠时间到就会立刻执行(因为睡眠过程中仍然保留着锁,有锁只要睡眠时间到就能立刻执行)。

  • sleep(): 睡眠指定时间,即让程序暂停指定时间运行,时间到了会继续执行代码,如果时间未到就要醒需要使用interrupt()来随时唤醒
  • interrupt(): 唤醒正在睡眠的程序,调用interrupt()方法,会使得sleep()方法抛出InterruptedException异常,当sleep()方法抛出异常就中断了sleep的方法,从而让程序继续运行下去
主动中止 vs 被动中止

A线程要B线程死
1)interrupt(); A 要 B停 —— 建议性中止
2)通过异常/通过B.isInterrupted/通过Thread.interrupted(检查自己)

B怎么就知道A要B死:
1) B正在睡眠(sleep/wait/join)
通知是以异常的形式给到:InterruputedException
2) B没有在睡眠
a. isInterrupted() 判断是否有人让我死
b. Thread.interrupted()

普通方法:interrupt() 通知线程停止(中断)
1)线程如果在休眠,会受到InterruptedException异常,状态位保持为false

2)线程如果没有在休眠,则状态位被修改为true

线程可以通过 普通方法 isInterrupted() 和静态**Thread.interrupted()**判断
1.isInterrupted()只获取当前状态,不会修改状态的值
2.Thread.interrupted() 获取当前状态,并且把状态修改为false

  • isInterrupted()任何线程都可以调用,只要有该线程的Thread对象
  • Thread.interrupted()查看当前线程的状态

线程什么时候退出,或者退不退出,由线程自行决定,建议性的通知

1.3 线程等待与线程唤醒

wait() 与 notify()

wait、notify和notifyAll方法是Object类的final native方法。所以这些方法不能被子类重写,Object类是所有类的超类,因此在程序中可以通过this或者super来调用this.wait(), super.wait()

  • wait(): 导致线程进入等待阻塞状态,会一直等待直到它被其他线程通过notify()或者notifyAll唤醒。该方法只能在同步方法中调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。 wait(long timeout): 时间到了自动执行,类似于sleep(long millis)
  • notify(): 该方法只能在同步方法或同步块内部调用, 随机选择一个(注意:只会通知一个)在该对象上调用wait方法的线程,解除其阻塞状态
    notifyAll(): 唤醒所有的wait对象

    注意:
    Object.wait()和Object.notify()和Object.notifyall()必须写在synchronized方法内部或者synchronized块内部
    让哪个对象等待wait就去通知notify哪个对象,不要让A对象等待,结果却去通知B对象,要操作同一个对象

1.4 等待退出

join()

  • join():A线程等待B线程退出(停止)
    能执行join()方法后面的语句,证明b线程已经结束,从run方法中退出
  • join(timeout) A会在timeout时间内等B停止

1.5 yield()方法

yield()
暂停当前方法,释放自己拥有的CPU,线程进入就绪状态。
它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权;但是,并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权;也有可能是当前线程又进入到“运行状态”继续运行!
但是执行了yield()方法,不会释放同步锁!
当释放了CPU,它和其他线程一起加入了就绪队列,拥有了抢占CPU的权利!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值