4.解决死锁方法2:notifyAll()方法,通知等待队列中的所有等待线程,可以去抢锁抢CPU了
Part1,2,3 代码示例:
public class Ts01 {
public static void main(String[] args) {
MyList list = new MyList();
Product p = new Product(list);
Product p1 = new Product(list);
Product p2 = new Product(list);
Customer c = new Customer(list);
p.start();
p1.start();
p2.start();
c.start();
}
}
class MyList {
private List list = new ArrayList();
private int MAX = 1;
// 添加
public synchronized void add(Integer i) {
//如果仓库已满,就释放锁,并且进入等待区
//如果被唤醒,立刻执行wait之后代码,即进入循环继续判断仓库是否已经满
while (list.size() >= MAX) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//仓库未满,开始生产
list.add(i);
System.out.println("库存" + list.size());
//生产完毕,通知等待区,随机唤醒一个线程(如果唤醒的是生产线程,那么继续唤醒)
//直到唤醒消费线程
notify();
}
// 取出
public synchronized Integer remove() {
//如果仓库为空,则进入等待区等待
//如果被唤醒,接着wait执行,继续判断仓库是否为空
while(list.isEmpty())
{
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//仓库不为空,开始消费
Integer i = list.remove(0);
//消费完毕,通知,唤醒等待区的随机线程。如果唤醒的是消费线程,那么继续唤醒
//直到唤醒生产线程
notify();
return i;
}
// 判空
public boolean isEmpty() {
return list.isEmpty();
}
}
// 生产者
class Product extends Thread {
private MyList list = null;
static int i = 1;
public Product(MyList list) {
this.list = list;
}
public void run() {
while (true) {
list.add(i);
System.out.println("增加了" + i);
i++;
}
}
}
// 消费者
class Customer extends Thread {
private MyList list = null;
public Customer(MyList list) {
this.list = list;
}
public void run() {
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Integer in = list.remove();
if (in != null)
System.out.println("移除" + in);
}
}
}
Part4,5,6,7 代码示例
public class Ts03 {
public static void main(String[] args) {
//Thread t = Thread.currentThread();
//System.out.println(t.getName());
//t.setPriority(newPriority)
//System.out.println(t.getPriority());
MyRunnable r = new MyRunnable();
new Thread(r).start();
}
}
class MyRunnable implements Runnable
{
@Override
public void run() {
while(true)
{
System.out.println("HelloWorld");
}
}
}
public class Ts03 {
public static void main(String[] args) {
//Thread t = Thread.currentThread();
//System.out.println(t.getName());
//t.setPriority(newPriority)
//System.out.println(t.getPriority());
MyRunnable r = new MyRunnable();
new Thread(r).start();
}
}
class MyRunnable implements Runnable
{
@Override
public void run() {
while(true)
{
System.out.println("HelloWorld");
}
}
}
Part8,9代码示例
public class Ts02 {
public static void main(String[] args) {
// //蜂蜜罐
// Jar jar = new Jar();
// //熊
// for (int i = 0; i < 2; i++) {
// new Thread(new Bear(jar)).start();
// }
// //蜜蜂
// for (int i = 0; i < 100; i++) {
// new Thread(new Bee(jar)).start();
// }
ManTouGuo m = new ManTouGuo();
for (int i = 0; i < 50; i++) {
new Thread(new Monk(m)).start();
}
}
}
//--------------------练习1---------------------------//
/*
* 1.熊吃蜂蜜问题
100只蜜蜂.
每只蜜蜂一次生产蜂蜜量为1.
蜜罐的容量是20.
熊在蜜罐满了的时候一次性吃掉所有蜂蜜。
提示:蜜蜂生产蜂蜜时,如果蜜罐已满则等待,否则+1,notifyAll.
熊吃蜂蜜时,如果蜜罐已满则吃掉再notifyAll,否则,notifyAll.
*/
class Jar{
//罐子最大蜂蜜量
public static final int MAX = 20;
//罐子当前蜂蜜量
public int count = 0;
//增加蜂蜜
public synchronized void add(){
//超过20.停止生产
while(count >= MAX){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//开始生产
count ++;
System.out.println("库存" + count);
//通知所有等待线程工作
notifyAll();
}
//吃蜂蜜
public synchronized void eat(){
//小于20,等待
while(count <20)
{
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//吃蜂蜜
count = count - 20;
//通知
notifyAll();
}
}
class Bee implements Runnable{
Jar jar;
public Bee(Jar jar){
this.jar = jar;
}
@Override
public void run() {
while(true){
jar.add();
System.out.println("蜜蜂产密,剩余" + jar.count);
}
}
}
class Bear implements Runnable{
Jar jar;
public Bear(Jar jar){
this.jar = jar;
}
@Override
public void run() {
while(true){
jar.eat();
System.out.println("熊吃蜂蜜,蜂蜜剩余" + jar.count);
}
}
}
//------------------------练习2-----------------------//
/*
* 2.和尚吃馒头问题
100馒头
50个和尚,每个和尚一次只能吃一个馒头,但是最多只允许吃三个馒头。
看每个和尚各吃了多少馒头。
*/
//馒头锅
class ManTouGuo
{
//剩余馒头总数
public int remainMTCount = 100;
//吃馒头
public synchronized void eat()
{
if(remainMTCount > 0)
{
remainMTCount --;
System.out.println("被吃了一个,剩余" + remainMTCount + "个馒头!");
}
}
}
//和尚
class Monk implements Runnable
{
//吃了多少个
int eatCount = 0;
//馒头锅
ManTouGuo mtg;
public Monk(ManTouGuo mtg)
{
this.mtg = mtg;
}
@Override
public void run() {
while( eatCount < 3 && mtg.remainMTCount >0 )
{
mtg.eat();
eatCount++;
}
System.out.println("我吃了" + eatCount + "个馒头!");
}
}
本文完!