Java multithreading of common Java interview questions (13)


121,什么是线程?

	线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通
	过它进行多处理器编程,可以使用多线程对运算密集型任务提速。比如,如果一个线程完成一个任务要100毫秒,
	那么用十个线程完成该任务只需要10毫秒

122,线程和进程有什么区别?

	在操作系统中,进程是程序的一次执行。在执行过程中,进程会申请,持有或释放操作系统资源。
	线程和进程非常相似,又被称为轻量级进程。一个进程可拥有多个线程,这些线程共享此进程所持有的系统资源。
	调度、执行的基本单位是线程,资源分配的基本单位是进程

123,如何在Java中实现线程?

	一种是继承Thread类,另一种是实现Runnable接口,当然使用Runnable最终还是要用到Thread

124,Java 关键字volatile 与 synchronized 作用与区别?

	1,volatile
	它所修饰的变量不保留拷贝,直接访问主内存中的。
	在Java内存模型中,有main memory,每个线程也有自己的memory (例如寄存器)。为了性能,一个线程会在自
	己的memory中保持要访问的变量的副本。这样就会出现同一个变 量在某个瞬间,在一个线程的memory中的值可
	能与另外一个线程memory中的值,或者main memory中的值不一致的情况。 一个变量声明为volatile,就意味
	着这个变量是随时会被其他线程修改的,因此不能将它cache在线程memory中。
	2,synchronized
	当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。
	一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一
	个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
	二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该
	object中的非synchronized(this)同步代码块。
	三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所
	有其它synchronized(this)同步代码块的访问将被阻塞。
	四、当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结
	果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
	五、以上规则对其它对象锁同样适用

 125,有哪些不同的线程生命周期?
 
	在Java程序中新建一个线程时,它的状态是New。当我们调用线程的start()方法时,状态被改变为Runnable。
	线程调度器会为Runnable线程池中的线程分配CPU时间并且将它们的状态改变为Running。其他的线程状态还有
	Waiting,Blocked和Dead

126,你对线程优先级的理解是什么?

	每一个线程都是有优先级的,一般来说,高优先级的线程在运行时会具有优先权,但这依赖于线程调度的实现,
	这个实现是和操作系统相关的(OSdependent)。我们可以定义线程的优先级,但是这并不能保证高优先级的线程
	会在低优先级的线程前执行。线程优先级是一个int变量(1-10)1代表最低优先级,10代表最高优先级

127,什么是死锁(Deadlock)?如何分析和避免死锁?

	死锁是指两个以上的线程永远阻塞的情况,这种情况产生至少需要两个以上的线程和两个以上的资源。
	分析死锁,查看Java应用程序的线程转储。找出那些状态为Blocked的线程和它们等待的资源。每个资源都有一
	个唯一的id,用这个id可以找出哪些线程已经拥有了它的对象锁。
	避免嵌套锁,只在需要的地方使用锁和避免无限期等待是避免死锁的通常办法

128,什么是线程安全?Vector是一个线程安全类吗? 

	如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和
	单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。一个线程安全的计数
	器类的同一个实例对象在被多个线程使用的情况下也不会出现计算失误。很显然你可以将集合类分成两组,线程
	安全和非线程安全的。Vector 是用同步方法来实现线程安全的, 而和它相似的ArrayList不是线程安全的

129,Java中如何停止一个线程?

	Java提供了很丰富的API但没有为停止线程提供APIJDK 1.0本来有一些像stop(), suspend()resume()
	的控制方法但是由于潜在的死锁威胁因此在后续的JDK版本中他们被弃用了,之后Java API的设计者就没有提供
	一个兼容且线程安全的方法来停止一个线程。当run() 或者 call() 方法执行完的时候线程会自动结束,如果要
	手动结束一个线程,你可以用volatile 布尔变量来退出run()方法的循环或者是取消任务来中断线程
 
130,什么是ThreadLocal?

	ThreadLocal用于创建线程的本地变量,我们知道一个对象的所有线程会共享它的全局变量,所以这些变量不是
	线程安全的,我们可以使用同步技术。但是当我们不想使用同步的时候,我们可以选择ThreadLocal变量。
	每个线程都会拥有他们自己的Thread变量,它们可以使用get()\set()方法去获取他们的默认值或者在线程内
	部改变他们的值。ThreadLocal实例通常是希望它们同线程状态关联起来是private static属性
        
131,Sleep()、suspend()和wait()之间有什么区别?

	sleep()会让线程停止,但此时线程仍然持有锁,并不会释放这些锁。另外一般使用时都会让线程停止指定的时
	间如1000毫秒
	suspend()会挂起线程直到另一个线程resume。但由于挂起时仍然会持有锁,很容易造成死锁。
	wait()也会让线程停止,但此时线程释放所持有的锁。一般和notify()配合使用

132,什么是线程饿死,什么是活锁?

	当所有线程阻塞,或者由于需要的资源无效而不能处理,不存在非阻塞线程使资源可用。JavaAPI中线程活锁可
	能发生在以下情形:
	1,当所有线程在程序中执行Object.wait(0),参数为0的wait方法。程序将发生活锁直到在相应的对象上有线
	程调用Object.notify()或者Object.notifyAll()2,当所有线程卡在无限循环中
        
133,什么是Java Timer类?如何创建一个有特定时间间隔的任务?

    java.util.Timer是一个工具类,可以用于安排一个线程在未来的某个特定时间执行。Timer类可以用安排一次
    性任务或者周期任务。
    java.util.TimerTask是一个实现了Runnable接口的抽象类,我们需要去继承这个类来创建我们自己的定时任
    务并使用Timer去安排它的执行
        
134,Java中的同步集合与并发集合有什么区别?

	同步集合与并发集合都为多线程和并发提供了合适的线程安全的集合,不过并发集合的可扩展性更高。
    在Java1.5之前程序员们只有同步集合来用且在多线程并发的时候会导致争用,阻碍了系统的扩展性。
    Java5介绍了并发集合像ConcurrentHashMap,不仅提供线程安全还用锁分离和    内部分区等现代技术提高了
    可扩展性
        
135,同步方法和同步块,哪个是更好的选择?

	同步块是更好的选择,因为它不会锁住整个对象(当然你也可以让它锁住整个对象)。同步方法会锁住整个对象,
	哪怕这个类中有多个不相关联的同步块,这通常会导致他们停止执行并需要等待获得这个对象上的锁

136,什么是线程池? 为什么要使用它?

	 创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线
	 程数有限。
	 为了避免这些问题,在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作
	 线程。
	 从JDK1.5开始,Java API提供了Executor框架让你可以创建不同的线程池。比如单线程池,每次处理一个
	 任务;数目固定的线程池或者是缓存线程池(一个适合很多生存期短的任务的程序的可扩展线程池)
        
137,Java中invokeAndWait 和 invokeLater有什么区别?

	这两个方法是Swing API 提供给Java开发者用来从当前线程而不是事件派发线程更新GUI组件用的。
	InvokeAndWait()同步更新GUI组件,比如一个进度条,一旦进度更新了,进度条也要做出相应改变。如果进度
	被多个线程跟踪,那么就调用invokeAndWait()方法请求事件派发线程对组件进行相应更新。而invokeLater()
	方法是异步调用更新组件的

138,多线程中的忙循环是什么

	忙循环就是程序员用循环让一个线程等待,不像传统方法wait(), sleep()yield() 它们都放弃了CPU控制,
	而忙循环不会放弃CPU,它就是在运行一个空循环。这么做的目的是为了保留CPU缓存。
	在多核系统中,一个等待线程醒来的时候可能会在另一个内核运行,这样会重建缓存。为了避免重建缓存和减少
	等待重建的时间就可以使用它了

Previous: Java Common Interview Questions: Database (12)
Next: Java Common Interview Questions: Java Generics (14)

Guess you like

Origin blog.csdn.net/Mr_TXQ/article/details/109047810