生产消费者模型
1.通过这个模型 成功的演示出了 线程安全的问题
两个消费者 同时访问同一个仓库对象 仓库内只有一个元素的时候
两个消费者并发访问 会有可能产生抢夺资源的问题
2.自己解决一下线程安全的问题
让仓库对象被线程访问的时候 仓库对象被锁定
仓库对象只能被一个线程访问 其它的线程处于等待状态
特征修饰符
synchronized 同步 一个时间点只有一个线程访问
线程安全锁(2种形式写法)
1.将synchronized关键字 放在方法的结构上
public synchronized void get(){}
锁定的是调用方法时的那个对象
2.将synchronized关键字 放在方法(构造方法 块)的内部
public void get(){
好多代码
synchronized(对象){
好多代码
}
好多代码
}
3.我们觉得return不是很好
应该让线程的不同状态来回切换
执行 等待 执行 等待
wait() Object类中的方法;//对象.wait(); 不是当前的这个对象wait,访问当前这个对象的线程wait;
wait()产生一个类似假死状态 所有的线程都进入等待状态 没有线程做事
notify () notifyAll() Object类中的方法
Thread.sleep();
run();
start();
多线程并发,可能出现抢资源;
不加线程安全锁,可能出现如下错误;
4.通过上述的生产消费者模型
做了一个非常完整而且安全的模型
1.利用线程安全锁 特征修饰符synchronized
两种不同的写法
不管怎么写 锁定的永远是对象
2.利用方法控制线程状态的来回切换
wait()
notify() notifyAll()
上述三个方法都是Object类中的方法
3.Thread类中的方法
sleep方法 静态方法(参数long 毫秒值)
setPriority(10); getPriority();
//设置线程的优先级 1-10 谁越高优先级越高 更加容易获取CPU分配的资源碎片
4.笔试题
程序 进程 线程 概念的区别
线程的创建方法
线程的几种状态 如何切换
sleep方法 wait方法的区别
1.类 Thread类 Object类
2.调用 静态 类名. 对象.
3.理解 (sleep)哪个位置调用 哪个线程等待;
(wait)哪个线程等待 访问对象的其他线程等待;
4.唤醒 不需要别人唤醒 需要其他对象调用notify()或notifyAll()唤醒
5.锁 不会释放锁 等待后会释放锁
5.join方法 Thread类中的方法
让多个线程同步执行 变成单个线程
6.死锁;
package test0604; import java.util.ArrayList; public class WareHouse{ private ArrayList<String> aa=new ArrayList<>(); public synchronized void add(){ if(aa.size()<20){ aa.add("a"); }else{ //return;//方法执行到这里就结束方法 try{ this.notifyAll(); this.wait();//仓库调用wait 不是仓库对象等待 访问仓库的生产者进入等待状态 }catch(InterruptedException e){ e.printStackTrace(); } } } public synchronized void get(){ //public void get(){ if(aa.size()>0){ aa.remove(0); }else{ //return; try{ this.notifyAll(); this.wait(); }catch(InterruptedException e){ e.printStackTrace(); } } } }
package test0604; public class Producer extends Thread{ private WareHouse house;//属性 public Producer(WareHouse house){ this.house=house; } public void run(){ while(true){ house.add(); System.out.println("生产者存入了一件货物"); try{ Thread.sleep(200); }catch(InterruptedException e){ e.printStackTrace(); } } } }
package test0604; public class Consumer extends Thread{ private WareHouse house; public Consumer(WareHouse house){ this.house=house; } public void run(){ while(true){ house.get(); System.out.println("消费者取出来一件货物"); try{ Thread.sleep(300); }catch(InterruptedException e){ e.printStackTrace(); } } } }
package test0604; public class TestMain{ public static void main(String[] args){ WareHouse house=new WareHouse(); Producer p=new Producer(house); //设置线程的优先级别1-10 p.setPriority(10); Consumer c=new Consumer(house); Consumer d=new Consumer(house); p.start(); c.start(); d.start(); } }