多线程基础知识
2015-07-30 10:39
239 查看
参考文章:http://blog.jobbole.com/18571/?from=singlemessage&isappinstalled=1
一、进程与线程
进程是为了提高CPU的执行效率,减少因为程序等待带来的CPU空转以及其他计算机软硬件资源的浪费而提出来的。进程是为了完成用户任务所需要的程序的一次执行过程和为其分配资源的一个基本单位,是一个具有独立功能的程序段对某个数据集的一次执行活动。进程是系统进行资源分配和调度的一个独立单位。
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
系统资源:线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行。
进程切换比线程切换开销大是因为进程切换时要切页表,而且往往伴随着页调度,因为进程的数据段代码段要换出去,以便把将要执行的进程的内容换进来。本来进程的内容就是线程的超集。而且线程只需要保存线程的上下文(相关寄存器状态和栈的信息)就好了,动作很小。
二、Java中多线程同步是什么?
在多线程程序下,同步能控制对共享资源的访问。如果没有同步,当一个Java线程在修改一个共享变量时,另外一个线程正在使用或者更新同一个变量,这样容易导致程序出现错误的结果。
三、实现多线程的几种方法?
Java线程可以实现Runnable接口或者继承Thread类来实现,当多重继承或资源共享时,使用Runnable接口。
四、Thread.start()与Thread.run()有什么区别?
Thread.start()方法(native)启动线程,使之进入就绪状态,当cpu分配时间该线程时,由JVM调度执行run()方法。start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面 的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。 然后通过此Thread类调用方法 run()来完成其运行操作的, 这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此线程终止。然后CPU再调 度其它线程。
五、Sleep()、suspend()和wait()之间有什么区别?
(1) 这两个方法来自不同的类分别是Thread和Object。wait是Object的方法,也就是说可以对任意一个对象调用wait方法,调用wait方法将会将调用者的线程挂起,直到其他线程调用同一个对象的notify方法才会重新激活调用者。
(2) 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
(3) wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
synchronized(x){
x.notify()
//或者wait()
}
(4) sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
suspend()是过时的方法,使用suspend()导致线程进入停滞状态,该线程会一直持有对象的监视器,suspend()容易引起死锁问题。
六、在静态方法上使用同步时会发生什么事?
同步静态方法时会获取该类的“Class”对象,所以当一个线程进入同步的静态方法中时,线程监视器获取类本身的对象锁,其它线程不能进入这个类的任何静态同步方法。它不像实例方法,因为多个线程可以同时访问不同实例同步实例方法。
七、什么是死锁
死锁就是两个或两个以上的线程被无限的阻塞,线程之间相互等待所需资源。这种情况可能发生在当两个线程尝试获取其它资源的锁,而每个线程又陷入无限等待其它资源锁的释放,除非一个用户进程被终止。就JavaAPI而言,线程死锁可能发生在一下情况。
● 当两个线程相互调用Thread.join()
● 当两个线程使用嵌套的同步块,一个线程占用了另外一个线程必需的锁,互相等待时被阻塞就有可能出现死锁。
八、什么是线程饿死,什么是活锁?
当所有线程阻塞,或者由于需要的资源无效而不能处理,不存在非阻塞线程使资源可用。JavaAPI中线程活锁可能发生在以下情形:
● 当所有线程在程序中执行Object.wait(0),参数为0的wait方法。程序将发生活锁直到在相应的对象上有线程调用Object.notify()或者Object.notifyAll()。
● 当所有线程卡在无限循环中。
一、进程与线程
进程是为了提高CPU的执行效率,减少因为程序等待带来的CPU空转以及其他计算机软硬件资源的浪费而提出来的。进程是为了完成用户任务所需要的程序的一次执行过程和为其分配资源的一个基本单位,是一个具有独立功能的程序段对某个数据集的一次执行活动。进程是系统进行资源分配和调度的一个独立单位。
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
系统资源:线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行。
进程切换比线程切换开销大是因为进程切换时要切页表,而且往往伴随着页调度,因为进程的数据段代码段要换出去,以便把将要执行的进程的内容换进来。本来进程的内容就是线程的超集。而且线程只需要保存线程的上下文(相关寄存器状态和栈的信息)就好了,动作很小。
二、Java中多线程同步是什么?
在多线程程序下,同步能控制对共享资源的访问。如果没有同步,当一个Java线程在修改一个共享变量时,另外一个线程正在使用或者更新同一个变量,这样容易导致程序出现错误的结果。
三、实现多线程的几种方法?
Java线程可以实现Runnable接口或者继承Thread类来实现,当多重继承或资源共享时,使用Runnable接口。
四、Thread.start()与Thread.run()有什么区别?
Thread.start()方法(native)启动线程,使之进入就绪状态,当cpu分配时间该线程时,由JVM调度执行run()方法。start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面 的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。 然后通过此Thread类调用方法 run()来完成其运行操作的, 这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此线程终止。然后CPU再调 度其它线程。
五、Sleep()、suspend()和wait()之间有什么区别?
(1) 这两个方法来自不同的类分别是Thread和Object。wait是Object的方法,也就是说可以对任意一个对象调用wait方法,调用wait方法将会将调用者的线程挂起,直到其他线程调用同一个对象的notify方法才会重新激活调用者。
(2) 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
(3) wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
synchronized(x){
x.notify()
//或者wait()
}
(4) sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
suspend()是过时的方法,使用suspend()导致线程进入停滞状态,该线程会一直持有对象的监视器,suspend()容易引起死锁问题。
六、在静态方法上使用同步时会发生什么事?
同步静态方法时会获取该类的“Class”对象,所以当一个线程进入同步的静态方法中时,线程监视器获取类本身的对象锁,其它线程不能进入这个类的任何静态同步方法。它不像实例方法,因为多个线程可以同时访问不同实例同步实例方法。
七、什么是死锁
死锁就是两个或两个以上的线程被无限的阻塞,线程之间相互等待所需资源。这种情况可能发生在当两个线程尝试获取其它资源的锁,而每个线程又陷入无限等待其它资源锁的释放,除非一个用户进程被终止。就JavaAPI而言,线程死锁可能发生在一下情况。
● 当两个线程相互调用Thread.join()
● 当两个线程使用嵌套的同步块,一个线程占用了另外一个线程必需的锁,互相等待时被阻塞就有可能出现死锁。
八、什么是线程饿死,什么是活锁?
当所有线程阻塞,或者由于需要的资源无效而不能处理,不存在非阻塞线程使资源可用。JavaAPI中线程活锁可能发生在以下情形:
● 当所有线程在程序中执行Object.wait(0),参数为0的wait方法。程序将发生活锁直到在相应的对象上有线程调用Object.notify()或者Object.notifyAll()。
● 当所有线程卡在无限循环中。
相关文章推荐
- UVa - The 3n + 1 problem 解读
- [转载] 关于matlab GUI的一点心得
- 深入PHP内核之array_multisort
- Ant 对java webapp打包war 的配置
- 自定义对象的调用
- 从头开始写项目Makefile(一):基本规则
- js dojo 保存txt文件
- 程序员如何爱护自己的眼睛
- 解决多个jquery并存冲突问题
- python积分scipy.integrate
- 对哈夫曼树的一点预习与理解
- iOS 十进制转十六进制
- Hive日期格式转换用法
- OpenGL关于glEnable(GL_LINE_STIPPLE) glLineStipple() glLineWidth() glDisable()的实例
- 居安思危,奋发图强,别整那些没用的
- HBase Shell 的常用操作总结
- Linux下查看CPU核数
- sql server创建临时表的两种写法和删除临时表
- 时间管理的一些小技巧
- spring mvc 上传文件