标签:java基础
以下的代码模拟了一个生产与消费的场景,一个票池,生产者不停的往里面放数据,消费则不停的取数据.
票池
class Pool{
private List<Integer> pool = new ArrayList<Integer>();
//添加元素
public void add(int i){
pool.add(new Integer(i));
}
//剪切元素
public Integer cut(){
if(!this.pool.isEmpty()){
return pool.remove(0);
}
return new Integer(0);
}
}
生产者
class Producer extends Thread{
private Pool pool;
public Producer(Pool pool){
this.pool = pool;
}
@Override
public void run() {
int i = 1;
while(true){
pool.add(i);
System.out.println("producor "+i);
i ++;
try {
this.sleep(400);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
消费者
class Consumer extends Thread{
private Pool pool;
public Consumer(Pool pool){
this.pool = pool;
}
@Override
public void run() {
while(true){
int tmp = pool.cut();
System.out.println("consumer " +tmp);
try {
this.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class ThreadDemo2 {
public static void main(String[] args) {
Pool pool = new Pool();
Producer p = new Producer(pool);
Consumer c = new Consumer(pool);
p.start();
c.start();
}
}
----------------------------------------------------分割线--------------------------------------------------------
考虑一下这种情况,现在想要为票池添加一个最大票数,在不超过最大票数的时候生产者才能放数据然后,当放满后通知消费者消费. 消费者在没有票的情况下等待,只有票池有票才能去消费 以下是实现的代码:
package Thread.Synchronized;
import java.util.ArrayList;
import java.util.List;
class Pool{
final static int MAX = 10;
private List<Integer> pool = new ArrayList<Integer>();
//添加元素
public void add(int i){
pool.add(new Integer(i));
}
//剪切元素
public Integer cut(){
if(!this.pool.isEmpty()){
return pool.remove(0);
}
return new Integer(0);
}
public int getPoolSize(){
return this.pool.size();
}
public List getPool(){
return this.pool;
}
}
class Producer extends Thread{
private Pool pool;
public Producer(Pool pool){
this.pool = pool;
}
@Override
public void run() {
int i = 1;
while(true){
synchronized (pool.getPool()) {
if(pool.getPoolSize()<Pool.MAX){
pool.add(i);
System.out.println("producor "+i);
i ++;
pool.getPool().notify();
try {
this.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
try {
pool.getPool().wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
class Consumer extends Thread{
private Pool pool;
public Consumer(Pool pool){
this.pool = pool;
}
@Override
public void run() {
int i;
while(true){
synchronized (pool.getPool()) {
//集合为空
try {
if(pool.getPool().size() == 0){
pool.getPool().wait();
}else{
i = pool.cut();
System.out.println("consumer " + i);
pool.getPool().notify();
this.sleep(200);
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
}
}
public class ThreadDemo2 {
public static void main(String[] args) {
Pool pool = new Pool();
Producer p = new Producer(pool);
Consumer c = new Consumer(pool);
p.start();
c.start();
}
}
将票池中的票数组最为监视器对象 所有线程的消费者和生产者都在注视着他的变化,生产者发现他满了就通知消费者,消费者取完票就通知生产者.
----------------------------------------------------分割线----------------------------------------------------------------
线程死锁
现在有这么一种场景,生产者在完成生产,消费者在完成消费,也就是说他们自身的行为后通知等待队列里的元素 去操作票池. 假设票池最大的量为1,一个生产者,两个消费者, 按以下步骤执行:
1.生产者生产一张票后发出通知后继续抢占CPU
2.生产者发现票池满了,进入等待队列,但他发出的通知唤醒了消费者C1
3.C1去消费了这张票后发出通知,继续抢占CPU
4.C1发现票池空了,进入等但队列,但他发出的通知唤醒了消费者C2
5.C2进入了去消费发现票池空了,没能取到票,所以没有发通知,直接进入了等待队列
6.现在 一个生产者,两个消费者全都困在等待队列中 这就造成了线程死锁.
标签:java基础
原文地址:http://pwitachi.blog.51cto.com/5057345/1770094