JAVA学习日记: 线程(7)
程序员文章站
2022-03-27 22:23:06
今天学习了的主要内容:1.什么是产生者消费者模型2.sleep()与wait()两个方法之间的差异产生者消费者模型:两个共享固定大小的缓冲区的线程,一个是往里面生成数据的,一个是往里面释放使用数据的,那么前者就是生产者,后者就是消费者。 生产者主要就是生成一定数量的数据在缓冲区供消费者线程使用, 一但到某个临界值,生产者就不会继续生产数据。 消费者就是消耗生产者产生的数据的线程, 一旦数据到某个临界值,就不再消耗。 我们关键就是要控制...
今天学习了的主要内容:
1.什么是产生者消费者模型
2.sleep()与wait()两个方法之间的差异
产生者消费者模型:
两个共享固定大小的缓冲区的线程,一个是往里面生成数据的,
一个是往里面释放使用数据的,
那么前者就是生产者,后者就是消费者。
生产者主要就是生成一定数量的数据在缓冲区供消费者线程使用,
一但到某个临界值,生产者就不会继续生产数据。
消费者就是消耗生产者产生的数据的线程,
一旦数据到某个临界值,就不再消耗。
我们关键就是要控制这两者的临界值!!
解决方法:
生产者解决方法:
让生产者在临界值休眠,然后等消费者从缓冲区消耗多个或者一个数据之后再唤醒。
消费者解决方法:
当缓冲区到那个临界值的时候,让消费者休眠,等生产者放入数据之后再唤醒。
sleep()与wait()两个方法之间的差异:
wait()方法是Object类提供的,sleep()方法是Thread类提供的。
wait()方法会把锁给打开,但是sleep()方法不会。
wait()方法只能用在同步方法里,sleep()方法可以用在任意地点。
Resourcese类(提供取钱存钱方法):
package LessonForThread07;
public class Resourcese
{
private int money = 0;
public int getMoney()
{
return money;
}
public void setMoney(int money)
{
this.money = money;
}
public synchronized void save()
{
//if (this.getMoney() != 0)
while (this.getMoney() != 0)//为了防止多个线程无序唤醒,我们将if换成while这样每进来一个线程就可以判断是否要wait了。
{
try
{
//wait()方法只能使用在同步方法中!!!synchronized修饰
wait();//使当前线程随调用这个方法的那个线程,等待另一个线程调用notify()方法唤醒时才继,他不能保证只有一个线程进来,它不锁定值
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
this.setMoney(this.getMoney()+10);
notify();//唤醒的是对方的wait,让当前调用线程wait唤醒另一个调用的线程苏醒。
System.out.println("余额:"+this.getMoney());
}
public synchronized void draw()
{
// if (this.getMoney() == 0)
while (this.getMoney() == 0)
{
try
{
wait();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
this.setMoney(this.getMoney()-10);
notify();
System.out.println("被取钱之后还剩余:"+this.getMoney());
}
}
Producer类(生产者):
package LessonForThread07;
public class Producer implements Runnable
{
private Resourcese save_money;
public Producer(Resourcese save_money)
{
this.save_money = save_money;
}
@Override
public void run()
{
for (int i=0; i<5; i++)
{
try
{
Thread.sleep(500);//存钱循环一次让出500ms
} catch (InterruptedException e)
{
e.printStackTrace();
}
save_money.save();
}
}
}
Customer类(消费者):
package LessonForThread07;
public class Customer implements Runnable
{
private Resourcese save_money;
public Customer(Resourcese save_money)
{
this.save_money = save_money;
}
@Override
public void run()
{
for (int i=0; i<5; i++)
{
try
{
Thread.sleep(500);//取钱循环一次让出500ms
} catch (InterruptedException e)
{
e.printStackTrace();
}
save_money.draw();
}
}
}
ThreadTest05类(测试notify和wait):
package LessonForThread07;
public class ThreadTest05
{
public static void main(String[] args)
{
Resourcese money = new Resourcese();
Producer p1 = new Producer(money);
new Thread(p1).start();
Producer p2 = new Producer(money);
new Thread(p2).start();
Producer p3 = new Producer(money);
new Thread(p3).start();
Customer c1 = new Customer(money);
new Thread(c1).start();
Customer c2 = new Customer(money);
new Thread(c2).start();
Customer c3 = new Customer(money);
new Thread(c3).start();
// Thread t1 = new Thread(p1);
// t1.start();
// Thread t2 = new Thread(c1);
// Thread t3 = new Thread(p1);
// t3.start();
// Thread t4 = new Thread(c1);
// Thread t5 = new Thread(p1);
// t5.start();
// Thread t6 = new Thread(c1);
// Thread t7 = new Thread(p1);
// t7.start();
// Thread t8 = new Thread(c1);
//
// t2.start();
// t4.start();
// t6.start();
// t8.start();
try
{
Thread.sleep(10000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("完毕");
}
}
本篇部分文字来源于:
咕嘟咖啡杨海滨老师 — 《java编程语言高级特性》
在这里十分感谢老师能够给我带来学习的激情。
2020.10.25
可以转载我的学习日记但请注明出处,谢谢。
本文章是本人学习笔记,不进行任何商用!也请别拿去商用!只为记录本人学习历程。
毕
本文地址:https://blog.csdn.net/SIESTA030/article/details/109272581