线程
1. 线程和进程的区别?
进程是当一个程序运行时候,从磁盘加载这个程序的代码到内存,这时就开启了一个进程,进程分为单实例进程和多实例进程,单实例进程就是打开的程序只能打开一份,多实例进程就是打开的程序可以打开多份。线程就是将一条一条的命令以一定顺序交给CPU执行,一个进程内包含一到多个线程。一个进程下的所有线程可以共享内存空间,线程是更轻量的,一个线程切换到另一个线程的成本更低。
2. 并行和并发有什么区别?
现在计算机都是多核CPU,并发是同一时间应对多件事情的能力,多个线程轮流使用一个或多个CPU。并行是同一时间动手做多件事情的能力,比如4核CPU同时执行4个线程。
3. 创建线程的方式有哪些?
创建线程一共有四种方式,第一种是当前类去继承Thread类,重写run()方法,通过new来创建当前类对象,调用start()方法来启动线程。第二种是当前类去实现Runnable接口,重写run()方法,通过new创建当前类对象,然后通过new创建Thread对象,将当前类对象传进去,最后调用start()方法启动线程。第三种是当前类去实现Callable<>接口它是有返回值适合用于要拿到当前线程结果,重写call()方法,通过new创建当前类对象,再new创建FutureTask<>对象,将当前类对象传进去,然后再通过new创建Thread对象,将FutureTask<>对象传进去,调用start()方法启动线程,最后再调用FutureTask<>对象的get()方法获取结果。第四种(项目中常用)是使用线程池创建线程,首先当前类要实现Runnable接口,重写run()方法,然后创建线程池对象,使用线程池的submit()方法提交当前线程任务,线程会自动执行,最后使用线程池的shutdown()方法关闭线程池。
4. 使用Runnable和Callable都可以创建线程,它们有什么区别呢?
Runnable是没有结果返回值的,并且它不能抛异常,而Callable有返回值的是个泛型并且可以抛异常。
5. 在启动线程的时候,可以使用run()方法吗?run()和start()有什么区别?
run()方法就相当于普通的方法调用,可以执行多次,而start()方法是通过线程来run()方法,只能调用一次。
6. 线程包括哪些状态?状态之间是如何变化的?
有6种状态,new、runnable、blocked、waiting、timed_waiting、terminated。首先通过new创建线程对象,执行start()方法进入runnable运行状态,如果拿到CPU执行权,正常执行后进入terminated终结状态。如果进入runnable运行状态这时候给它加了个锁,那就会进入blocked阻塞状态,释放了锁拿到执行权后才会切换回运行状态。然后如果在runnable状态调用了wait()方法就会进入waiting等待的状态,只有当调用了notify()方法后才会让它继续变成可执行状态。最后如果是调用了sleep()方法,就会进入timed_waiting时间等待状态,等到达时间就变成可运行状态。
7. 新建T1、T2、T3三个线程,如何保证它们按顺序执行?
可以使用线程中的join()方法解决,它就是等待线程运行结束嘛,调用了此方法的线程进入timed_waiting直到执行完此线程再继续执行,比如T2线程中的T1线程调用了join(),T3线程中的T2线程调用了join(),那就是T2要等T1执行完再执行,然后T3等T2执行完再执行。
8. notify()和notifyAll()有什么区别?
notify()是随机唤醒一个wait()的线程,而notifyAll()是唤醒所有wait()的线程。
9. Java中的wait()和sleep()方法有什么不同?
共同点:wait()、wait(long)、sleep(long)都能让当前线程暂时放弃CPU的使用权,进入阻塞状态。不同点:首先是方法的归属不同,sleep()是Thread的静态方法,而wait()是Object的成员方法,每个对象都有。其次是醒来的时机不同,wait(long)和sleep(long)都会等待相应毫秒后醒来,wait()、wait(long)还可以被notify唤醒,wait()如果不唤醒就一直等待下去,最后是它们都可以被打断唤醒。最后(重点)是锁特性不同,必须要加锁才能调用wait()方法,而sleep则不用加锁也能调用,wait()执行后会释放锁并进入空闲等待,允许其他线程获得该对象锁(就是我放弃CPU,但你们可以用),而sleep()如果在synchronized代码块中执行,并不会释放对象锁(我放弃CPU,你们也用不了)。
10. 如何停止一个正在运行的线程?
有3种方式可以停止线程,第一种是加上退出标记,达到退出标记时间使线程正常退出,也就是当run()方法完成后线程终止。第二种是使用stop()方法强行终止(已作废,不推荐)。第三种是使用interrupt()方法中断线程,它分为2种情况,首先是打断阻塞的线程(wait、sleep、join)的线程,线程会抛出InterrupteException异常,然后就是打断正常的线程,根据打断状态来标记是否退出线程。
网硕互联帮助中心





评论前必须登录!
注册