(2)多线程-线程的常用方法与生命周期

线程常见方法

Thread.currentThread().getName()); 获取当前线程的名称

thread.setName(线程名称), 设置线程名称

thread.isAlive() 判断当前线程是否处于活动状态;活动状态就是线程已启动并且尚未终止

thread.getId() 可以获得线程的唯一标识
注意:某个编号的线程运行结束后,该编号可能被后续创建的程使用,重启的 JVM 后,同一个线程的编号可能不一样

中断线程:注意调用interrupt() 方法仅仅是在当前线程打一个停止标志,并不是真正的停止线程

thread.setPriority( num ); 设置线程的优先级
java 线程的优先级取值范围是 1 ~ 10,如果超出这个范围会抛出异常 IllegalArgumentException.
在操作系统中,优先级较高的线程获得CPU的资源越多线程优先级本质上是只是给线程调度器一个提示信息,以便于调度器决定先调度哪些线程. 注意不能保证优先级高的线程先运行
Java 优先级设置不当或者滥用可能会导致某些线程永远无法得到运行,即产生了线程饥饿.
线程的优先级并不是设置的越高越好,一般情况下使用普通的优
先级即可,即在开发时不必设置线程的优先级
线程的优先级具有继承性, 在 A 线程中创建了 B 线程,则 B 线程的
优先级与 A 线程是一样的

Thread.yield() 方法的作用是放弃当前的 CPU 资源
yield() 暂停当前方法,释放自己拥有的CPU,线程进入就绪状态。它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权;但是,并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权;也有可能是当前线程又进入到“运行状态”继续运行!

join()

join()是Thread类的一个方法,根据jdk文档的定义,join()方法的作用,是等待这个线程结束,即当前线程等待另一个调用join()方法的线程执行结束后在往下执行。通常用于在main主线程内,等待其它调用join()方法的线程执行结束再继续执行main主线程。

主线程等待子线程执行完毕后再执行

public static void main(String[] args) {
        try {
            MyThread myThread = new MyThread();
            myThread.start();
            myThread.join();
            System.out.println("等子线程执行完再执行");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

sleep()

在指定时间内让当前执行的线程暂停执行一段时间,让其他线程有机会继续执行,但不会释放对象锁,也就是说如果有synchronized同步块,其他线程仍然不能访问共享数据,不推荐使用。sleep() 使当前线程进入阻塞状态,在指定时间不会执行,因此sleep()方法常用来暂停线程的执行,当sleep()结束后,然后转入到 Runnable(就绪状态),这样才能够得到执行的机会。

wait()、notify和notifyAll()

在synchronized 代码块执行,说明当前线程一定是获取了锁的。当线程执行wait()方法的时候,会释放当前的锁,然后让出CPU,进入等待状态。只有当 notify/notifyAll() 被执行时候,才会唤醒一个或多个正处于等待状态的线程,然后继续往下执行,直到执行完synchronized 代码块的代码或是中途遇到wait() ,再次释放锁。也就是说,notify/notifyAll() 的执行只是唤醒沉睡的线程,而不会立即释放锁,锁的释放要看代码块的具体执行情况。所以在编程中,尽量在使用了notify/notifyAll() 后立即退出临界区,以唤醒其他线程让其获得锁

线程sleep和wait的区别

  • 1、sleep方法是Thread类的静态方法,wait()是Object超类的成员方法

  • 2、sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。在调用sleep()方法的过程中,线程不会释放对象锁;
    而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备

  • 3、sleep方法需要抛异常,wait方法不需要

  • 4、sleep方法可以在任何地方使用;
    wait方法只能在同步方法和同步代码块中使用

sleep和yield的区别

  • 1.sleep()方法暂停当前线程后,会给其他线程执行机会,不会理会其他线程的优先级;但yield()方法只会给优先级相同,或优先级更高的线程执行机会。

  • 2.sleep()方法会将线程转入阻塞状态,直到经过阻塞时间才会转入就绪状态;而yield()方法不会将线程转入阻塞状态,它只是强制当前线程进入就绪状态。因此完全有可能某个线程调用yield()方法暂停之后,立即再次获得处理器资源被执行。

  • 3.sleep()方法声明抛出了InterruptedException异常,所以调用sleep()方法时要么捕捉该异常,要么显式声明抛出该异常;而yield()方法则没有声明抛出任何异常。

  • 4.sleep()方法比yield()方法有更好的可移植性,通常不建议使用yield()方法来控制并发线程的执行。

线程的生命周期

线程有5中状态新建->就绪->运行->阻塞->死亡
1、新建状态(New): 当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();

2、就绪状态(Runnable): 当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;

3、运行状态(Running):
当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

4、阻塞状态(Blocked): 处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:

1、等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;

2、同步阻塞:线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

3、其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

5、死亡状态(Dead): 线程执行完了或者因异常退出了run()方法,该线程结束生命周期。在jvm启动后,实际上有多个线程,但是至少有一个非守护线程

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值