java多线程之面试题

java多线程之面试题

 

 

怎么理解多线程?

 

1. 让应用程序在一个时间段做多个事情,提高效率

2. 可以实现异步的效果,主线程马上返回成功,子线程继续去工作

 

 

 

程序、进程、线程的关系

 

一个程序,就有一个进程,一个进程中可以有多个线程,其中又分为主线程和子线程。

 

 

 

理解并发与并行

 

并发:通过CPU调度算法,让用户看上去同时执行,实际上,是通过CPU在高速切换,并不是真正的额同时

并行:多个CPU实例或者多台机器同时执行一段处理逻辑,这就是真正的同时;

 

 

 

如何创建线程?

 

1. 继承Thread

2. 实现Runnable接口(优先选择)

 

注意:

1. 都要重写run()方法

2. 调用thread.start(),线程才真正启动

 

 

 

线程的各种状态

 

可执行(Runnable):当调用start()方法后,一个线程变为可执行状态,但是并不意味着他会立刻开始真正地执行。而是被放入线程池,由线程调度器根据线程优先级决定何时挂起执行。

 

执行中(Running):处理器已经在执行线程的代码。他会一直运行直到被阻断,或者通过静态方法Thread.yield()自行放弃执行的机会,考虑到场景切换所带来的开销,yield()方法不应该被经常调用。

 

等待中(Waiting):线程由于等待I/O等外部进程的处理结果而处于被阻断的状态,调用currObject.wait( )方法会使得当前线程进入等待状态,直到其它线程调用currObject.notify() 或者currObject.notifyAll() 。

 

睡眠中(Sleeping):重载方法Thread.sleep(milliseconds),Thread.sleep(milliseconds, nanoseconds)可以迫使Java线程进入睡眠状态(挂起)。

 

由于I/O阻塞(Blocked on I/O):当I/O条件发生变化时(例如读取了几个字节的数据)会迁移到可执行状态。

 

由于同步阻塞中(Blocked on synchronization): 当获取锁之后会进入执行中状态。

 

 

 

多线程一般怎么用?

 

线程池,线程池工作原理

 

 

 

为什么要用线程池

 

1. 对于一些简单的工作,每次创建和销毁线程,比较耗资源

2. 每次创建和销毁线程,也让程序变慢

3. 每个进程的中,可以创建的线程是有限的,为了保护服务器,这也是必须的

 

 

 

Java线程池中submit() 和 execute()方法有什么区别?

 

两个方法都可以向线程池提交任务,execute()方法的返回类型是void,它定义在Executor接口中, 而submit()方法可以返回持有计算结果的Future对象,它定义在ExecutorService接口中,它扩展了Executor接口,其它线程池类像ThreadPoolExecutor和ScheduledThreadPoolExecutor都有这些方法。

 

 

 

什么是多线程的线程安全

 

保证共享资源在多线程的情况下不会出现错乱。

 

 

 

如何保证线程安全

 

synchronized

同步方法、同步类、同步块

缺点:不灵活

 

Lock

可重入锁

读写锁

1. 多个读同时读,不加锁

2. 多个写互斥

3. 有读有写,写优先,如果读写同时等待,那优先唤醒写

缺点:手动释放锁

 

同步集合、并发集合

同步集合:HashTable、Vector、Collections中的同步方法

并发集合:ConcurrentHashMap、CopyOnWriteArrayList、CopyOnWriteHashSet

 

Volatile

 

不变类

 

 

 

什么时候会出死锁

 

两个线程同时占有对方要的资源

如:

线程1有资源A,要资源B

线程2有资源B,要资源A

 

死锁发生的条件:

互斥条件:一个资源每次只能被一个进程使用。

请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

 

解决方法:

有序资源分配法

银行家算法

 

 

 

如何控制线程

 

闭锁、栅栏、信号量

join控制线程有序进行

 

 

 

项目中用到哪些

 

信号量、线程池

 

 

 

如果同步块内的线程抛出异常会发生什么?

 

无论你的同步块是正常还是异常退出的,里面的线程都会释放锁;至于Lock就要在finally中释放锁

 

 

 

wait()和sleep()的区别

 

wait() 释放锁,sleep() 不释放锁

wait() 要notify() 或 notifyAll() 才有机会获得锁,sleep() 一段时间后,自动继续

 

 

http://www.importnew.com/12773.html

 

猜你喜欢

转载自youyu4.iteye.com/blog/2400935