|
一、多线程(一)概念 进程:正在进行中的程序 进程就是应用程序在内存中的运行空间 线程:线程就是进程中的执行路径 一个进程中至少有一个线程 多线程:进程中的多条执行路径【多段代码同时执行】 JVM:是多线程的 垃圾回收器、主线程main 垃圾回收器调用对象的finalize方法回收垃圾。System.gc()告诉JVM启动垃圾回收器。 主线程的任务代码都在main函数中 (二)弊端多线程是开辟多条路径,CPU切换是需要耗费资源的。 (三)创建多线程方式一:Thread run(); 线程任务 Start(); 启动线程 getName(); 获取线程名称 currentThread(); 返回当前正在运行线程的引用 方式二:Runnable (四)线程状态创建 --- 运行 -(阻塞<--冻结)--停止 sleep wait notify
运行:具有执行资格和执行权 阻塞:具有执行资格,没有执行权 冻结:没有执行资格,没有执行权 file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps1B5B.tmp.jpg (五)线程安全问题原因:多线程、多条共享语句 解决:同步锁 synchronized(对象){同步代码} 同步函数(锁,this): public synchronized void add(){} 静态同步函数(锁,Class) public static synchronized void add(){} 同步前提:使用同一个锁 同步弊端:需要判断同步锁,因此效率相对低 (六)死锁同步的嵌套会产生死锁,死锁代码我们需要避免发生 if(flag){ while(true){ Synchronized(A){ Synchronized(B){ //同步代码1 } } } }else{ while(true){ Synchronized(B){ Synchronized(A){ //同步代码2 } } } } (七)线程间通信多个线程处理同一资源,但任务不同 wait();notify();noifyAll(); Input ---[Resource] --- Output 多生产者,多消费者 资源 ---烤鸭 RoastedDuck 任务1--生产者 Producer 任务2--消费者 Consumer //烤鸭 class RoastedDuck{ private boolean flag = false; private String name; private int num; public synchronized void set(String name){ while(flag) try{wait();}catch(InterruptedException e){} this.name = name; num++; System.out.println("生产者生产了第"+num+"只"+name); flag = true; notifyAll(); } public synchronized void get(){ while(!flag) try{wait();}catch(InterruptedException e){} System.out.println("消费者消费了第"+num+"只"+name); flag = false; notifyAll(); } } //生产者 class Producer implements Runnable{ private RoastedDuck rd; Producer(RoastedDuck rd){ this.rd = rd; } public void run(){ while(true){ rd.set("烤鸭"); } } } //消费者 class Consumer implements Runnable{ private RoastedDuck rd; Consumer(RoastedDuck rd){ this.rd = rd; } public void run(){ while(true){ rd.get(); } } }
|