一.多进程
- 一个进程就是一个独立的应用程序。
- 一个进程独占一块内存空间。
- “同时运行多个线程”:并非绝对意义上的同时,实际上是CPU在不同的进程间进行来回切换,因为速度太快,人感受不到。
二.线程
概念:线程是进程内部独立的运行流程。
1. 优点:同一进程中的线程共享内存地址空间(资源)。两个线程间通信方便。
2. CPU在线程之间来回切换,让人感觉线程在同时运行。线程间的切换消耗资源更小。
3. java常见线程:main方法,gc。
三.Java实现多线程
1.继承Thread类
public class ThreadA extends Thread{
public void run(){
}
public static void main(String[] args){
ThreadA ta = new ThreadA();
ta.start();//必须调用ta对象的start方法。
}
}
虽然调用run方法和start方法实现效果类似。但是前者只是一个普通的方法调用,主线程会把执行权交给run方法,当run方法结束后再回到main方法。start方法中包含了更多的处理,这样才开启了一个线程。
必须实现run方法,run方法相当于main方法。
2.实现Runnable接口
public class ThreadB implements Runnable{
public void run(){
}
public static void main(String[] args){
ThreadB tb = new ThreadB();
Thread t = new Thread(tb);
}
}
但是必须依附于一个Thread对象。调用的时候,先要创建一个Thread对象,再传一个实现了Runnable接口的类的对象。如果有参数则调用传入对象的start方法。
四.线程的生命周期。
1.新建状态
new出Thread对象。
2.就绪状态
调用了start方法,但在start方法中调用run方法之前的状态。
3.运行状态
4.死亡状态
当run方法执行完毕时
5.中断状态
当run方法开始执行时。
(1)睡眠:调用线程的sleep(<毫秒数>)方法。结束休眠后仍然要参与到CPU的抢夺中。
(2)等待/唤醒:调用Object的wait()方法。自己wait,另外一个线程notify唤醒等待中的第一个线程,还有notifyAll唤醒所有等待的线程。被唤醒后同样要参与到CPU的抢夺中。
(3)挂起:调用yield()方法。强制让某个线程退出CPU的执行。
(4)阻塞:线程在执行输入输出这样的IO操作,等待IO事件。
(5)由于优先级的原因,线程没有抢到CPU处于中断状态。
五.线程的优先级
线程的优先级一共分为10级,最小为1,最大为10,默认为5.
Thread t = new Thread();
t.setPriority(<优先级>);
但是优先级高只能代表该线程被CPU执行的几率更高,并不是优先级高的执行完毕才能执行优先级低的。
六.线程的安全性
当多个线程同时访问同一资源的时候才会考虑线程安全性问题。
解决方法:同步锁
1.什么是同步锁
谁先访问,谁先操作,如果没有操作完,第二个线程才能访问。所以效率会变低。
2.同步方法
public void synchronized methodxxx()
方法前面加上synchronized修饰符。
tips:虽然发生的可能性很低,但是多个线程访问同一资源必须加同步锁。
七.死锁
1.概念
当两个或多个线程同步访问一对循环依赖的资源时就会发生死锁的现象。*
2.如何解决死锁,wait和notify。
(1)wait和notify方法只能够写在同步方法和同步块当中。
(2)死锁的情况存在,但是代码模拟很难。