线程的运行都是独立的,但是存在多个线程需要同时访问共享的资源时,需要用到线程的同步(synchronized),就相当于在共享的对象资源上加了一把锁,每次只能一个线程获得对象锁。最简
单的例子:如卖电影票,几个窗口(线程)同时对电影票进行销售,彼此线程都是互斥的,每次只能一个线程去访问电影票(这个对象)。但是也存在一种生产者-消费者的流程,这时需要用到线程的交互(wait()与notify()/notifyAll(),等待-唤醒),比如写个生产包子与卖包子的例子,每次生产包子到100个后就通知去卖包子,当卖包子到0时,就通知生产包子。
1:定义一个包子对象,
public class Manager{
private int count;//包子的数量
private String name;//包子的名称
public int maxcount=100;//包子的最大数量
public boolean k;//用于判断包子是否还有,默认是FALSE,用true代表包子有,通知消费,用false代表包子没有,通知生产。
//构造函数
public Manager(String name,int count){
this.name=name;
this.count=count;
}
public int getCount(){
return this.count;
}
public int setCount(int y){
return this.count+=y;
}
}
//定义一个生产包子的线程
public class Producer implements Runnable{
private Manager ma;//定义一个共享对象
public Producer(Manager ma){
this.ma=ma;//保证传递进来的是同一个共享对象
}
public void run(){
//因为不知道是生产线程先运行还是消费线程先运行,所以必须先判断
while(true){
//无限循环,保证卖完就生产
synchronized(ma){//传递对象锁
if(ma.k==true){//状态为true,代表包子已经有了,就等待,通知消费。
ma.wait();//这里需要添加try-catch,一旦包子数量有,则需要消费线程去 notify(),当前线程就等待唤醒。
}
if(ma.getCount<100){//当包子数量少于100个,就生产
ma.setCount(5);
System.out.println("生产了5个,总量为;"+ma.getCount());
}
ma.k=true;//包子数量大于100个了,所以改变状态
ma.notify();//通知消费者去消费
}
}
}
}
//定义一个消费线程
public class Custer implements Runnable{
private Manager ma;
public Custer(Manager ma){
this.ma=ma;
}
public void run(){
while(true){
synchronized(ma){
if(ma.k==false){
ma.wait();//当包子的状态为false,代表消费需要等待生产。
}
if(ma.getCount()>0){
ma.setCount(-2);
System.out.println("包子已经消费2个,剩下:"+ma.getCount());
}
ma.k=false;//包子已经消费完了,需要生产。
ma.notify();
}
}
}
}
//定义一个主线程类,开始运行
public class Testdemo{
public static void main(String[] args){
Manager ma=new Manager("包子",0);//定义一个包子对象
Producer p=new Producer(ma);//创建生产对象
Custer c=new Custer(ma); //创建消费对象
Thread t1=new Thread(p);//创建生产线程对象
Thread t2=new Thread(c); //创建消费线程对象
t1.start();//启动生产线程
t2.start(); //启动消费线程
}
}