网站收录了文章不收录,亚马逊周末可以视频认证吗,影视后期行业前景,wordpress设置为繁体字文章目录 线程与进程区别并行与并发区别解析概念含义资源利用执行方式应用场景 创建线程线程状态如何保证新建的三个线程按顺序执行wait方法和sleep方法的不同所属类和使用场景方法签名和参数说明调用wait方法的前提条件被唤醒的方式与notify/notifyAll方法的协作使用示例注意事… 文章目录 线程与进程区别并行与并发区别解析概念含义资源利用执行方式应用场景 创建线程线程状态如何保证新建的三个线程按顺序执行wait方法和sleep方法的不同所属类和使用场景方法签名和参数说明调用wait方法的前提条件被唤醒的方式与notify/notifyAll方法的协作使用示例注意事项 停止线程的三种方式 线程与进程区别 进程的定义与实例 进程是当程序被运行从磁盘加载程序代码到内存时开启的。例如打开谷歌浏览器或txt文档等程序就是开启了一个进程在Windows中有多实例进程可打开多份如浏览器、txt文档和单实例进程如tears客户端、企业微信在系统层面只能打开一份。 线程的定义与作用 线程包含指令交给CPU运行。进程至少包含一到多个线程每个线程执行不同任务。 线程与进程的区别 进程是正在运行的程序实例包含多个线程执行不同任务。不同进程使用不同内存空间而当前进程下的所有线程可以共享该进程的内存空间。线程更轻量其上下文切换成本一般比进程上下文切换成本低。面试时主要回答这三点进程和线程的关系、内存占用情况强调进程下线程共享内存、线程更轻量且切换成本低。 并行与并发区别解析
概念含义
并行同一时间动手做多件事情的能力。例如在多核CPU下多个核心可以同时执行不同的线程像四核CPU能同时执行四个线程这些线程是真正意义上的同时进行。并发同一时间应对多件事情的能力。在单核CPU中由于只有一个核心多个线程不能同时执行而是通过任务管理器分配时间片轮流使用CPU虽然每个时间片只有一个线程执行但因CPU切换速度快宏观上给人一种并行的感觉微观上实际是串行执行。例如家庭主妇独自做饭、打扫卫生、给孩子喂奶一个人轮流交替做这些事就如同单核CPU处理多线程任务。
资源利用
并行需要多核CPU等硬件资源支持每个核心可以独立运行一个线程实现真正的同时处理多个任务充分利用了多核CPU的计算能力提高了整体任务处理效率。并发主要依赖于操作系统的调度机制在单核CPU环境下通过合理分配时间片给不同线程让多个任务看起来像是同时在处理有效利用了单个CPU的时间资源避免某个线程长时间占用CPU导致其他线程等待过久但整体效率受限于单核CPU的处理能力。
执行方式
并行多个任务在多个处理器或多核CPU的不同核心上同时执行任务之间相互独立不存在资源竞争除非访问共享资源时需要进行同步处理执行顺序是真正意义上的同时进行。并发多个任务在单核CPU上通过时间片轮转的方式交替执行每个任务执行一段时间后暂停切换到下一个任务由于时间片很短给用户造成任务在同时进行的错觉但实际上在微观层面是串行执行的任务之间可能存在频繁的上下文切换开销。
应用场景
并行适用于计算密集型任务如大规模数据处理、复杂科学计算等通过将任务分解到多个核心上同时计算可以显著缩短计算时间提高计算性能。例如在图像渲染、视频编码解码等领域利用多核CPU并行处理不同部分的图像或视频数据能快速完成处理工作。并发常用于I/O密集型任务如网络通信、文件读写等操作这些任务在等待I/O操作完成时会阻塞线程使用并发可以在等待一个任务的I/O操作时切换到其他任务执行提高CPU利用率避免线程长时间空闲等待。比如在一个Web服务器中同时处理多个客户端的请求每个请求在等待数据库查询或文件读取等I/O操作时服务器可以切换去处理其他客户端请求提高整体响应能力。 创建线程 创建线程的方式介绍 创建线程共有四种方式分别是继承Thread类、实现Runnable接口、实现Callable接口和使用线程池创建线程。 继承Thread类创建线程 定义一个类继承Thread类重写run方法在run方法中编写线程要执行的代码。使用时先创建该类的对象然后调用start方法开启线程new两次对象相当于开两个线程。 实现Runnable接口创建线程 定义一个类实现Runnable接口重写run方法该方法为线程执行的代码。使用时先创建类的对象将其包装在Thread类中再调用Thread对象的start方法开启线程new两次对象相当于开两个线程。 实现Callable接口创建线程 定义一个类实现Callable接口重写call方法call方法有返回值通过泛型指定且可抛异常call方法的代码为线程要执行的逻辑。使用时先创建类的对象配合FutureTask包装该对象再将FutureTask包装在Thread类中调用Thread对象的start方法开启线程通过FutureTask的get方法获取线程执行后的返回值。 使用线程池创建线程 创建一个类实现Runnable或Callable接口编写线程执行逻辑。使用时先创建固定大小的线程池线程池后期会详细讲解通过线程池的submit方法提交任务即实现接口的类的对象线程池会自动执行线程中的逻辑。 Runnable和Callable的区别 返回值Runnable接口的run方法无返回值Callable接口的call方法有返回值且需配合FutureTask使用get方法获取返回值。异常处理run方法不能抛异常只能内部try - catch处理call方法可以抛异常。 start方法和run方法的区别 功能start方法用于启动线程线程独立执行run方法中的代码run方法是普通方法直接调用如同调用普通方法在当前线程顺序执行代码。调用次数start方法只能被调用一次启动线程多次调用会抛异常run方法可多次调用。 总结 创建线程有继承Thread类、实现Runnable接口、实现Callable接口和使用线程池四种方式项目中一般使用线程池创建线程。Runnable和Callable的区别主要在返回值、异常处理方面。start方法用于启动线程且只能调用一次run方法是普通方法可多次调用。 线程状态
线程状态面试题介绍 状态定义参考Thread类的内部枚举类State定义了六个线程状态即new新建、runnable可运行、block阻塞、waiting等待、time waiting时间等待、terminated终结。 线程状态及转换初步讲解 新建状态创建线程对象时进入如创建线程t1和t2时。就绪与运行状态调用线程方法后进入就绪状态抢到CPU时间片才有执行权线程运行完成后进入死亡状态。阻塞状态线程加锁时未获得锁的线程进入阻塞状态获得到锁后转为可运行状态。等待状态线程内部调用wait方法进入等待状态其他线程调用notify或notifyAll方法唤醒后变为可运行状态。时间等待状态线程调用sleep方法进入时间等待状态时间结束后转为可运行状态。 总结线程状态及转换 线程状态总结包含六个状态新建、可运行、阻塞、等待、计时等待、终止状态。状态转换关系梳理 新建到可执行创建线程对象为新建状态调用方法后转换为可执行状态。可执行到终止线程获取CPU执行权并执行结束后为终止状态。可执行状态的其他转换 可执行到阻塞未获取到锁如synchronized或Lock锁进入阻塞状态获得到锁的执行权后切换为可执行状态。可执行到等待调用wait方法进入等待状态其他线程调用notify或notifyAll唤醒后切换为可执行状态。可执行到计时等待调用sleep方法进入计时等待状态时间到后切换为可执行状态。 文章目录 线程与进程区别并行与并发区别解析概念含义资源利用执行方式应用场景 创建线程线程状态如何保证新建的三个线程按顺序执行wait方法和sleep方法的不同所属类和使用场景方法签名和参数说明调用wait方法的前提条件被唤醒的方式与notify/notifyAll方法的协作使用示例注意事项 停止线程的三种方式 如何保证新建的三个线程按顺序执行
方法介绍 对于“如何保证新建t1、t2、t3三个线程按顺序执行”这一面试题可使用线程中的“join方法”来解决。该方法的作用是等待线程运行结束调用此方法的线程会被阻塞进入time waiting时间等待状态直到被调用“join方法”的线程执行完成后调用者才能继续执行。 代码演示在代码中创建了t1、t2、t3三个线程在t2线程中调用了t1的“join方法”这意味着t2线程想要运行必须等待t1线程结束在t3线程中调用了t2的“join方法”所以t3线程需等待t2线程运行结束后才能运行。启动线程的顺序不影响最终结果最终会按t1、t2、t3的顺序执行。通过代码执行结果展示了t1先执行完成后t2执行t2执行完t3执行从而验证了这种方法可保证线程按顺序执行。 notify和notifyAll的区别 为notify是只随机唤醒一个等待wait方法的线程而notifyAll是唤醒所有等待方法的线程。 wait方法和sleep方法的不同 在Java中wait方法用于使当前线程等待直到其他线程调用该对象的notify方法或notifyAll方法唤醒它或者等待一定的时间如果指定了超时时间。以下是关于wait方法的详细介绍
所属类和使用场景
所属类wait方法属于Object类这意味着Java中的任何对象都可以调用该方法。使用场景主要用于多线程编程中实现线程之间的协作和同步。例如当一个线程需要等待某个条件满足时可以调用wait方法进入等待状态直到其他线程改变了共享资源的状态并通知它。
方法签名和参数说明
方法签名public final void wait() throws InterruptedException和public final native void wait(long timeout) throws InterruptedException。参数说明 无参的wait方法会使当前线程无限期等待直到被唤醒。带参数的wait方法接受一个long类型的参数表示等待的超时时间以毫秒为单位。如果在指定时间内没有被唤醒线程会自动苏醒并继续执行。
调用wait方法的前提条件
当前线程必须拥有该对象的锁。也就是说wait方法必须在同步代码块synchronized块中调用否则会抛出IllegalMonitorStateException异常。例如以下代码演示了正确调用wait方法的方式
synchronized (object) {// 当前线程获取了object对象的锁可以调用wait方法object.wait();
}被唤醒的方式
其他线程调用notify方法唤醒在此对象监视器上等待的单个线程。如果有多个线程在等待选择是任意的由操作系统的调度策略决定。其他线程调用notifyAll方法唤醒在此对象监视器上等待的所有线程。被唤醒的线程将竞争重新获取对象的锁然后继续执行。等待超时如果调用了带超时参数的wait方法当超时时间到达时线程会自动苏醒继续执行后续代码。
与notify/notifyAll方法的协作
wait方法与notify/notifyAll方法必须在同一对象上调用以实现线程之间的正确协作。通常一个线程在等待某个条件时调用wait方法而另一个线程在改变条件后调用notify或notifyAll方法来唤醒等待的线程。
使用示例
以下是一个简单的示例展示了wait方法和notify方法的基本用法
public class WaitNotifyExample {public static void main(String[] args) {final Object lock new Object();// 线程1等待条件满足Thread thread1 new Thread(() - {synchronized (lock) {try {System.out.println(线程1开始等待);lock.wait(); // 释放锁并等待System.out.println(线程1被唤醒继续执行);} catch (InterruptedException e) {e.printStackTrace();}}});// 线程2改变条件并通知线程1Thread thread2 new Thread(() - {synchronized (lock) {System.out.println(线程2改变条件并通知线程1);lock.notify(); // 唤醒等待的线程1}});thread1.start();try {Thread.sleep(1000); // 确保线程1先进入等待状态} catch (InterruptedException e) {e.printStackTrace();}thread2.start();}
}在上述示例中线程1获取lock对象的锁后调用wait方法进入等待状态同时释放锁。线程2获取lock对象的锁后调用notify方法唤醒线程1线程1被唤醒后重新竞争锁获取锁后继续执行后续代码。
注意事项
在使用wait方法时必须在循环中调用以避免虚假唤醒spurious wakeup的问题。虚假唤醒是指线程在没有被其他线程明确唤醒的情况下苏醒可能是由于操作系统或JVM的内部原因。例如
while (condition) {synchronized (object) {object.wait();}
}调用wait方法的线程会释放对象的锁但在被唤醒后重新竞争锁。如果多个线程同时竞争锁唤醒顺序是不确定的取决于操作系统的调度策略。wait方法会抛出InterruptedException异常当线程在等待过程中被中断时会抛出该异常。因此在调用wait方法时需要正确处理异常以确保程序的稳定性和正确性。 文章目录 线程与进程区别并行与并发区别解析概念含义资源利用执行方式应用场景 创建线程线程状态如何保证新建的三个线程按顺序执行wait方法和sleep方法的不同所属类和使用场景方法签名和参数说明调用wait方法的前提条件被唤醒的方式与notify/notifyAll方法的协作使用示例注意事项 停止线程的三种方式 停止线程的三种方式
停止线程的三种方式 使用退出标志通过定义一个标志变量如flag在run方法中使用循环条件控制线程执行当标志变量改变时线程正常退出。例如在my interrupt 1类中run方法里使用while循环while (!flag)线程在循环内打印信息并睡眠3秒。主线程启动该线程后睡眠6秒然后将flag改为true使线程在6秒后正常退出。调用stop方法不推荐stop方法可以强行终止线程但此方法已作废不推荐使用。调用interrupt方法该方法包含两种情况。 一是打断阻塞的线程如处于sleep、wait、join状态的线程调用interrupt会抛出InterruptException异常二是打断正常的线程可根据线程的打断状态标记是否退出线程与第一种使用退出标志的方式类似。