进程和线程的区别:
1. 什么是进程
- 进程是指在系统中正在运行的一个应用程序,程序一旦运行就是进程;
- 一个进程可以拥有多个线程,每个线程使用其所属进程的栈空间;
2. 什么是线程
- 是指进程内的一个执行单元,也是进程内的可调度实体;
3. 进程和线程的区别
- 地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间;
- 资源共享:进程之间不能共享资源,而线程共享所在进程的地址空间和其它资源。同时线程还有自己的栈和栈指针,程序计数器等寄存器;
- 执行过程:每个独立的进程程有一个程序运行的入口、顺序执行序列和程序入口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制;
- 线程是处理器调度的基本单位,但是进程不是;
- 两者均可并发执行;
简而言之,一个程序至少有一个进程,一个进程至少有一个线程。
Callable和Runnable的区别
相同点:
- Callable和Runnable都是接口;
- 都可以用于实现多线程程序;
- 都需要调用Thread.start()启动线程;
不同点:
- Callable规定的方法是call(),该函数有返回值,返回执行结果,此时需要调用FutureTask.get()方法实现,此方法会阻塞主线程直到获取‘将来’结果;Runnable规定的方法是run(),该函数没有返回值;
- Callable接口的call()方法允许抛出异常;而Runnable接口不可以;
- Callable和Runnable都可以应用于executors。而Thread类只支持Runnable;
sleep和wait的区别
- sleep()方法是属于Thread类中的方法,而wait()方法,则是属于Object类中的方法;
- sleep()方法不会释放锁,到时间后会继续执行;wait()方法释放了锁,并需要notify/notifyAll后重新获取到对象锁资源后才能继续执行,使得其他线程可以使用同步控制块或者方法;
- wait(),notify()和notifyAll()只能在同步控制方法或者同步控制块里面使用,而sleep()可以在任何地方使用
- sleep()必须捕获异常,而wait(),notify()和notifyAll()不需要捕获异常
解决线程同步安全问题的方法
同步代码块:
- 使用 synchronized() 对需要完整执行的语句进行“包裹”,synchronized(Obj obj) 构造方法里是可以传入任何类的对象;
同步方法:
- synchronized 修饰的方法——方法中的所有代码,都只允许一个线程访问;
锁机制Lock:
- 创建ReentrantLock对象;
- 调用lock方法:加锁;
{代码…} - 调用unlock方法:解锁(可把解锁的unlock方法的调用放在finally{}代码块中,保证一定能解锁);
synchronized锁和Lock锁的区别
- synchronized是java内置关键字,在jvm层面,Lock是个java类,通过这个类可以实现同步访问;
- synchronized会自动释放锁(a 线程执行完同步代码会释放锁 ;b 线程执行过程中发生异常会释放锁),Lock需在finally中手工释放锁(unlock()方法释放锁),否则容易造成线程死锁;
- Lock是可以中断锁,Synchronized是非中断锁,必须等待线程执行完成释放锁。
- Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少量的同步问题。
如何实现多线程
- 继承Thread类,重写run方法;
- 实现Runnable接口,重写run方法;
- 通过线程池创建线程;
- 通过Callable和FutureTask创建线程
线程池的优点和缺点
线程池常用类型:
- newFixedThreadPool():创建一个定长线程池,该方法返回一个固定线程数量的线程池,该线程池中的线程数量始终不变;
- newCachedThreadPool:创建一个可缓存线程池,该方法返回一个可以根据实际情况调整线程池中线程的数量的线程池。如果没有线程不够用则会一直创建,有空闲线程则会复用;
- newScheduledThreadPool():创建一个定长线程池,支持定时及周期性任务执行;
- newSingleThreadExecutorr():创建一个单线程化的线程池,多余的任务会存在队列中等待执行;
线程池的优点:
- 降低资源消耗,通过重复利用已经创建的线程降低线程创建和销毁造成的消耗;
- 提高响应速度,当任务达到时,任务可以不需要的等到线程创建就能够立即执行;
- 提高线程的可管理性,性程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,故使用线程池可以进行统一的分配,调用和监控,但是也要做到合理的利用线程池,所以要对线程池的原理了如指掌;
线程池的缺点:
- 线程池不支持线程的取消、完成、失败通知等交互性操作;
- 线程池不支持线程执行的先后次序排序;
- 线程池效率降低了资源消耗同时也降低了效率和速度;