(1)Java并发编程基础篇

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/JavaMrZhang/article/details/87689642

什么是线程

CPU调度的最基本单位。

线程创建与运行

线程的创建有三种方式

  1. 通过继承Thread类覆盖run方法

  2. 实现runnable接口

  3. 实现Callable接口,此方式能够获取任务执行完毕的返回结果

线程通知与等待

  1. wait方法

当一个线程调用共享变量的wait函数时,该线程会阻塞挂起并释放共享变量的锁. 线程的唤醒需由其他线程通过调用共享变量的notify方法或notifyAll方法。但有可能存在虚假唤醒的情况,所以程代码的一般写法都是如下,以保障程序的健壮性.

synchroized(shareVariable){
    
    while(quque.size() == MAX_SIZE){
        // 阻塞挂起
        shareVariable.await();
    }
    
}

     2. wait(long timeout)方法

线程调用共享变量的wait(long timeout),在指定timeout时间内如果没其他线程调用共享变量的notify或notifyAll方法,该线程将会因为超时而自动唤醒。需要注意的是 timeout=0 和不传入参数时方法功能时相同的,timeout=-1将会抛出IllegalArgumentsException异常。

     3. notify()方法

该方法会随机唤醒一个因调用共享变量wait方法而挂起的线程,唤起的线程会继续开始和其他线程争抢共享变量的监视器锁.

     4. notifyAll()方法

该方法则会唤醒全部因调用共享变量wait方法而挂起的线程,让所有的线程继续争抢共享变量的监视器锁。

     5. Thread的join方法

A线程调用了B线程的join方法时,A线程将会阻塞挂起,等待B线程任务结束唤醒它继续执行。

     6. Thread的sleep方法

线程调用此方法之后会进入休眠状态,出让CPU执行权,只有等到指定睡眠时间过后,才会继续参与CPU调度。需要注意的是:该线程锁持有的共享变量监视器锁资源仍然是不释放的。

     7. yield方法

线程会出让CPU执行权,并处于就绪状态,等待CPU调度器分配下一轮时间片。

     8. 线程中断

线程的中断并不是终止线程的执行,而是通过设置中断标志位,让被中断的线程根据中断标志位自行处理。

  • interrupt()

对线程进行中断操作,只是设置了线程中断的标志位,线程仍然能够继续执行。需要注意的是对于阻塞挂起的线程如果调用了中断操作将会抛出IntteruptedException异常

  • isInterrpted()

检测线程是否被中断(线程是否设置了中断标志位)

  • interrupted()

检测线程是否被中断,此方法与isInterrpt()不同之处在于:interrupted为Thread的静态方法、调用之后会清除中断标志位,isInterrpt调用之后并不会清楚中断标志位。

应用场景:

线程为了等待某些资源调用sleep方法让其进行阻塞挂起30s,但是等待的资源早在2s内就完成了。如果一直等到30s再返回有点浪费时间,这时就可以调用该线程的interrupt方法,抛出异常让线程恢复到激活状态。

上下文切换

当线程将CPU分配的时间片用完之后,会处于就绪状态等待和其他线程继续竞争CPU资源来进行下次的执行,此步骤就是上下文切换。为了保证线程下次分配到CPU时间片继续执行,所以线程上下文切换的时候需要保存执行现场。

守护线程和用户线程

主线程执行完毕后, 如果存在用户线程,那么JVM进程是不会结束。

主线程执行完毕后,如果只存在守护线程,那么JVM进程会立马结束。

主线程也是用户线程

猜你喜欢

转载自blog.csdn.net/JavaMrZhang/article/details/87689642