大家好,又见面了,我是你们的朋友全栈君。
● 概念
线程:进程中负责程序执行的执行单元。一个进程中至少有一个线程。
多线程:解决多任务同时执行的需求,合理使用CPU资源。多线程的运行是根据CPU切换完成,如何切换由CPU决定,因此多 线程运行具有不确定性。
线程池:基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。
● 线程
创建线程的两种方式:
一、继承Thread类,扩展线程。
代码语言:javascript复制class DemoThread extends Thread { @Override public void run() { super.run(); // Perform time-consuming operation... } } DemoThread t = new DemoThread(); t.start();
- 继承Thread类,覆盖run()方法。
- 创建线程对象并用start()方法启动线程。
面试题
- 1)线程和进程有什么区别?
一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。
- 2)如何在Java中实现线程?
创建线程有两种方式: 一、继承 Thread 类,扩展线程。 二、实现 Runnable 接口。
- 3)Thread 类中的 start() 和 run() 方法有什么区别?
调用 start() 方法才会启动新线程;如果直接调用 Thread 的 run() 方法,它的行为就会和普通的方法一样;为了在新的线程中执行我们的代码,必须使用 Thread.start() 方法。
二、实现Runnable接口。
- 1)用 Runnable 还是 Thread ?
我们都知道可以通过继承 Thread 类或者调用 Runnable 接口来实现线程,问题是,创建线程哪种方式更好呢?什么情况下使用它?这个问题很容易回答,如果你知道Java不支持类的多重继承,但允许你调用多个接口。所以如果你要继承其他类,当然是调用Runnable接口更好了。
● 线程的状态以及状态之间的相互转换
1、新建状态(New):新创建了一个线程对象。
2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
(一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
(三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
- wait和sleep的区别:
线程访问:
锁池状态,之后等待锁释放,然后访问代码
wait
等待队列(释放资源)—>调用notify或者notifyall之后锁池状态—>( 等待锁释放)—>可运行状态—>运行状态—->访 问代码
sleep,join
不释放资源–>结束后直接进入可运行状态—>运行状态—->访问代码
一个java控制台程序,默认运行两个线程,一个主线程,一个垃圾回收线程。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/139890.html原文链接:https://javaforall.cn