进程和线程这块去看os这块的进程知识
这本书很好
继承Thread类
实现多线程的时候,要注意
- 需要继承Thread类
- 必须重写run方法,核心执行的逻辑
- 线程在启动的时候不要直接调用run方法,而是要通过start()方法来进行调用
public class ThreadDemo extends Thread{ public void run(){ for(int i = 0; i < 10; i++){ // coding } } public static void main(String[] args){ ThreadDemo ThreadDemo = new ThreadDemo(); ThreadDemo.start(); for(int i = 0; i < 5; i++){ // coding } } }
如果像下面这么写,只会运行main这个线程
public class ThreadDemo extends Thread{ public void run(){ for(int i = 0; i < 10; i++){ // coding } } public static void main(String[] args){ ThreadDemo ThreadDemo = new ThreadDemo(); ThreadDemo.run(); for(int i = 0; i < 5; i++){ // coding } } }
实现Runnble接口(推荐使用,因为java单继承,将继承关系留给最需要的类;方便共享资源)
使用了代理设计模式
- 实现了runnable方法
- 重写run方法
- 创建Thread类,将刚刚创建好得到runnbale的自类实现作为thread类的构造参数
- 通过Thread.start()进行启动
- 使用runnable接口之后不需要给共享变量添加static关键字,每次创建一个对象
public class TicketRunnable implements Runnable{ private int ticket = 5; public void run(){ for(int i = 0; i < 100; i++){ if(ticket > 0){ // coding } } } public static void main(String[] args){ TicketRunnable ticket = new TicketRunnable(); TicketThread t1 = new Tread(ticket); TicketThread t2 = new Tread(ticket); TicketThread t3 = new Tread(ticket); TicketThread t4 = new Tread(ticket); t1.start(); t2.start(); t3.start(); t4.start(); } }
线程声明周期
- 新生状态,创建好当前线程对象之后,没有启动之前(调用start方法前)
- 就绪状态,准备开始执行,并没有执行,表示调用start方法之后
- 运行状态,当前进程获取CPU资源后,就绪对立中的线程抢占CPU
- 死亡状态,运行中线程正常执行完所有代码逻辑,因为异常情况导致程序结束
- 阻塞状态,发生某些异常情况,导致当前线程无法顺利执行下去,紧入阻塞状态,阻塞结束后进入就绪状态
五状态模型
如何进入死亡状态
- 正常结束
- 人为中断执行,stop方法
- 程序抛出未捕获的异常
如何进入阻塞状态
- sleep方法
- 等待io资源
暂停/停止线程的方法
- sleep,当前线程处于阻塞状态
- yield,暂停正在进行的线程,允许其他线程进行,不阻塞,如果没有其他执行的线程,当前线程会立马执行
- join,当某个线程等待另一个线程执行结束后,才继续执行,调用该方法的线程在此前执行完毕,等待调用该方法的线程执行完毕后执行
- stop,强制结束线程,暴力结束
同步
- 每次启动线程对象的时候都会创建自己对象的属性值,没有真正实现共享
- 将共享对象,共享变量设置成static
- 每次访问共享对象时,数据不一致
- 此时使用线程同步,即加锁
同步的前提
- 必须有两个或两个以上的线程
- 必须是多个线程使用同一资源
- 必须保证同步中只能有一个线程运行
CAS 无锁式同步机制
同步代码块synchronized(共享资源,共享对象,需要Object的子类)
public class SleepTest implements Runnable{ private int ticket = 5; public void run(){ for(int i = 0; i < 100; i++){ try{ Thread.sleep(200); }catch(Exception e){ e.printStackTrace(); } synchronized(this){ if(ticket > 0){ // coding } } } } public static void main(String[] args){ TicketRunnable ticket = new TicketRunnable(); TicketThread t1 = new Tread(ticket, "A"); TicketThread t2 = new Tread(ticket, "B"); TicketThread t3 = new Tread(ticket, "C"); TicketThread t4 = new Tread(ticket, "D"); t1.start(); t2.start(); t3.start(); t4.start(); } }
synchronized,同步方法,不需要指定共享对象
public class SleepTest implements Runnable{ private int ticket = 5; public void run(){ for(int i = 0; i < 100; i++){ this.sale(); } } public void synchronized sale(){ try{ Thread.sleep(200); }catch(Exception e){ e.printStackTrace(); } if(ticket > 0){ // coding } } public static void main(String[] args){ TicketRunnable ticket = new TicketRunnable(); TicketThread t1 = new Tread(ticket, "A"); TicketThread t2 = new Tread(ticket, "B"); TicketThread t3 = new Tread(ticket, "C"); TicketThread t4 = new Tread(ticket, "D"); t1.start(); t2.start(); t3.start(); t4.start(); } }
同步监视器
synchronized(obj){}中的obj称为同步监视器
生产者-消费者
get和set加同步锁
加信号量同步
wait(),进入阻塞状态,notify,进入唤醒状态
JUC,Java Util Concurrent
1.5以后出的新功能