首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
并发编程线程基础
并发编程的其他基础知识
Java并发包中的ThreadLocalRandom类原理剖析
Java并发包中原子操作类原理剖析
Java并发包中并发List源码剖析
Java并发包中锁原理剖析
Java并发包中并发队列原理剖析
Java并发包中线程池ThreadPoolExecutor原理探究
Java并发包中ScheduledThreadPoolExecutor原理探究
Java并发包中线程同步器原理剖析
当前位置:
首页>>
技术小册>>
Java并发编程
小册名称:Java并发编程
## wait() 如果调用wait()方法的线程没有实现获取该对象的监视器锁,则调用wait()方法时线程会抛出IllegalMonitorStateException异常。 一个线程获取一个共享变量的监视器锁的方法 - 执行synchronized同步代码块时,使用该共享变量作为参数: ```java synchronized(共享变量) { //do something } ``` - 调用该共享变量的方法,并且该方法使用了synchronized修饰: ```java synchronized void add(int a, int b) { //do something } ``` > 注意:一个线程可以挂起状态变成运行状态(也就是被唤醒),即使该线程没有被其他线程调用notify()、notifyAll()方法进行通知,或者被中断,或者等待超时,这就是所谓的**虚假唤醒**。 虚假唤醒在实践中很少发生,但要防患于未然,如下: ```java synchronized(obj) { while(条件不满足) { obj.wait(); } } ``` ## notify()和notifyAll() notify()会唤醒被阻塞到该共享变量上的一个线程,notifyAll()会唤醒所有在该共享变量上由于调用wait系列方法而被挂起的线程。 ## join() ```java ... public static void main(String[] args){ ... thread1.join(); thread2.join(); System.out.println("all child thread over!"); } ``` 主线程首先会在调用thread1.join()后被阻塞,等待thread1执行完毕后,thread2开始阻塞,以此类推,最终会等所有子线程都结束后main函数才会返回。 ## sleep() sleep()会使线程暂时让出指定时间的执行权,也就是在这期间不参与CPU的调度,但不会释放锁。 ## yield() 线程调用yield()方法时,实际上是暗示线程调度器当前线程请求让出自己的CPU使用(告诉线程调度器可以进行下一轮的线程调度),但线程调度器可以无条件忽略这个暗示。 ## 线程中断 ### void interrupt() 设置线程的中断标志为true并立即返回,但线程实际上并没有被中断而会继续向下执行;如果线程因为调用了wait系列函数、join方法或者sleep方法而被阻塞挂起,其他线程调用该线程的interrupt()方法会使该线程抛出InterruptedException异常而返回。 ### boolean isInterrupted() 检测当前线程是否被中断,是则返回true,否则返回false。 ### boolean interrupted() 检测当前线程是否被中断,返回值同上,但如果发现当前线程被中断,会清除中断标志;该方法是**static**方法,内部是获取当前调用线程的中断标志而不是调用interrupted()方法的实例对象的中断标志。 ### 示例 ```java public static void main(String[] args){ Thread threadOne = new Thread(new Runnable(){ @Override public void run() { for(;;) { } } }); //启动线程 threadOne.start(); //设置中断标志 threadOne.interrupt(); //获取中断标志 System.out.println("isInterrupted:" + threadOne.isInterrupted() ); //获取中断标志并重置 System.out.println("isInterrupted:" + threadOne.interrupted() ); //获取中断标志并重置 System.out.println("isInterrupted:" + Thread.interrupted() ); //获取中断标志 System.out.println("isInterrupted:" + threadOne.isInterrupted() ); try{ threadOne.join(); }catch(InterruptedException e) { System.out.println("interrupted!!!"); } System.out.println("main thread is over"); } ``` 输出为 ```java isInterrupted:true isInterrupted:false isInterrupted:false isInterrupted:true ``` 解析 threadOne.interrupted()一句,由于interrupted()为static方法,相当于执行Thread.interrupted()。 ## 守护进程与用户进程 当最后一个用户进程结束时,JVM会正常退出,而不管当前是否有守护进程。 ### 示例 ```java public static void main(String[] args){ Thread t = new Thread(new Runnable(){ @Override public void run() { for(;;) {} } }); // t.setDaemon(true); t.start(); System.out.println("main is over"); } ``` 运行后发现虽然输出了"main is over",但ide运行状态红框仍亮着,说明JVM进程未结束,如图: ![](/uploads/images/20231216/45d1f5831f4507a4a90fab0fe86b06da.png) 打开注释后程序则快速退出。
下一篇:
并发编程的其他基础知识
该分类下的相关小册推荐:
Java语言基础16-JDK8 新特性
SpringBoot合辑-高级篇
Java语言基础3-流程控制
Java并发编程实战
SpringBoot合辑-初级篇
Java语言基础9-常用API和常见算法
Java语言基础7-Java中的异常
Java语言基础10-Java中的集合
Java必知必会-Maven初级
Mybatis合辑5-注解、扩展、SQL构建
Java语言基础2-运算符
Java语言基础5-面向对象初级