[Java]线程问题

1、生产者消费者问题

wait() 必须在synchronized 函数或者代码块里面

wait()会让已经获得synchronized 函数或者代码块控制权的Thread暂时休息,并且丧失控制权

这个时候,由于该线程丧失控制权并且进入等待,其他线程就能取得控制权,并且在适当情况下调用notifyAll()来唤醒wait()的线程。

需要注意的是,被唤醒的线程由于已经丧失了控制权,所以需要等待唤醒它的线程结束操作,从而才能重新获得控制权。

所以wait()的确是马上让当前线程丧失控制权,其他的线程可以乘虚而入。

 

此例中:

当产品仓库满的时候,生产者线程需要wait(),从而放弃对产品仓库的控制。

这个时候消费者线程就可以进来了而取得仓库的控制权。一旦消费者消费了产品,那么仓库就不满了。

这个时候消费者线程就要notifyAll()生产者线程,让等待的生产者线程唤醒。

但是生产者被唤醒后不能马上进行生产,因为它在wait()的时候已经丧失了对仓库的控制权,所以就需要等待消费者线程结束操作,

才能重新取得仓库的控制权,再进行生产。

所以特别注意的是,notifyAll()并不是让当前线程马上让出控制权,而只是让其他wait()当中的线程唤醒而已,

所以对不起,尽管我唤醒你,可你必须还是要等我用完仓库才能进来。这点必须清楚。

相反,仓库如果空的时候,消费者线程就会wait(),然后等待生产者线程来生产产品,生产者进程乘虚而入后,让生产者线程生产产品

并且唤醒消费者线程。这个情况跟上面就类似了。

 

package threadProblems;

public class ProducerConsumer {
	public static void main(String args[]) {
		Basket basket = new Basket();
		Producer producer = new Producer(basket);
		Consumer comsumer = new Consumer(basket);
		new Thread(producer).start();
		new Thread(comsumer).start();
	}
}

class Producer implements Runnable {
	Basket basket;

	public Producer(Basket b) {
		this.basket = b;
	}

	public void run() {
		for (int i = 0; i < 20; i++) {
			basket.push(i);
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class Consumer implements Runnable {
	Basket basket;

	public Consumer(Basket b) {
		this.basket = b;
	}

	public void run() {
		for (int i = 0; i < 20; i++) {
			int j = basket.pop();
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class Basket {
	int[] basket = new int[6];
	int index = 0;

	public synchronized int pop() {
		while (index == 0) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.notify();
		index--;
		System.out.println("编号: " + basket[index] + " 被消费");
		return basket[index];
	}

	public synchronized void push(int i) {
		while (index == 6) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.notify();
		basket[index] = i;
		System.out.println("编号: " + i + " 被生产");
		index++;
	}
}


 

2、造一个死锁的程序

package threadProblems;

public class TestDeadLock implements Runnable {
	public int flag = 1;
	public Object o1;
	public Object o2;

	public void run() {
		if (flag == 1) {
			synchronized (o1) {
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				synchronized (o2) {
					System.out.println("1");
				}
			}
		}
		if (flag == 2) {
			synchronized (o2) {
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				synchronized (o1) {
					System.out.println("2");
				}
			}
		}
	}

	public static void main(String args[]) {
		TestDeadLock t1 = new TestDeadLock();
		TestDeadLock t2 = new TestDeadLock();
		t1.flag = 1;
		t2.flag = 2;
		Object o1 = new Object();
		Object o2 = new Object();
		t1.o1 = o1;
		t1.o2 = o2;
		t2.o1 = o1;
		t2.o2 = o2;
		new Thread(t1).start();
		new Thread(t2).start();
	}
}


 

3、使用三个线程打印分别打印A、B、C   10次    保持ABC的顺序不变

package threadProblems;

public class PrintABCtenTimes {
	public static int count = 0;

	public static void main(String args[]) {
		Object lockObj = new Object();
		Printer pa = new Printer(0, lockObj, "A");
		Printer pb = new Printer(1, lockObj, "B");
		Printer pc = new Printer(2, lockObj, "C");
		new Thread(pa).start();
		new Thread(pb).start();
		new Thread(pc).start();
	}
}

class Printer implements Runnable {
	int i;
	String s;
	Object lockObj;

	public Printer(int i, Object lockObj, String s) {
		this.i = i;
		this.lockObj = lockObj;
		this.s = s;
	}

	public void run() {
		for (int j = 0; j < 10; j++) {
			synchronized (lockObj) {
				while (true) {
					if (PrintABCtenTimes.count % 3 == i) {
						System.out.print(s);
						PrintABCtenTimes.count++;
						lockObj.notifyAll();
						break;
					} else {
						try {
							lockObj.wait();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}
	}
}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值