一、进程与线程的区别?
进程是所有线程的集合,每一个线程是进程中的一条执行路径,线程只是一条执行路径。
二、创建线程的三种方式:
继承Thread类创建线程类
实现Runnable接口
通过Callable和Future创建线程
三、创建线程池的四种方式:(参考1)
newCachedThreadPool
创建一个可缓存的线程池,如果线程池长度超过处理需求,可灵活回收空闲线程,若无可回收,则新建线程
newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行
newSingleThreadExecutor
创建一个单线程化的线程池,它只会唯一的工作线程来执行任务,保证所有任务按照指定
顺序(FIFO,LIFO,优先级)执行
四、线程安全及解决
当多个线程同时共享,同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题。做读操作是不会发生数据冲突问题。
使用线程同步或使用锁能解决线程安全问题,只能让当前一个线程进行执行。被包裹的代码执行完成后释放锁,让后才能让其他线程进行执行。这样的话就可以解决线程不安全问题。
解决多线程同步问题:
(1)同步代码块
(2)同步函数
(3)静态同步函数
同步代码块与同步函数区别?
同步代码使用自定锁(明锁)
同步函数使用this锁
同步函数与静态同步函数区别?
注意:
面试会这样问:例如现在一个静态方法和一个非静态方法怎么实现同步?(参考2)
同步函数使用this锁(实例对象本身)
静态同步函数使用字节码文件,也就是类.class(类对象本身)
五、什么是多线程死锁?
同步中嵌套同步,无法释放锁的资源。
解决办法:同步中尽量不要嵌套同步
六、Wait()与Notify ()区别?
Wait让当前线程有运行状态变为等待状态,和同步一起使用
Notify 唤醒现在正在等待的状态,和同步一起使用
七、Wait()与sleep()区别?
sleep()方法,该方法是属于Thread类中的。
wait()方法,则是属于Object类中的。
sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。
在调用sleep()方法的过程中,线程不会释放对象锁。
而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。
八、读写锁(参考3)
读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。
何谓自旋锁?它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。