阻塞队列步步升华

[size=x-large][b]1、首先我们定义一个简单的队列。这个队列可以不断的往队列中放数据,一个放数据的线程,一个取数据的线程。队列可以无限大,所以这样会有内存泄露的危险。[/b][/size]
package com.zte;

import java.util.Random;
import java.util.Vector;


public class SimpleQueue {

Vector<Integer> vector = new Vector<Integer>();

public synchronized void put(){
System.out.println(Thread.currentThread().getName() + ",开始放数据。");
vector.add(new Random().nextInt(1000));
System.out.println(Thread.currentThread().getName() + ",已放完数据。");
System.out.println("队列中还有:" + vector.size());
this.notify(); //只是通知另外的线程你可以获得锁,如果本线程获取了锁,其他线程也是获取不到锁的
}

public synchronized Integer get(){
System.out.println(Thread.currentThread().getName() + ",开始取数据。");
while(vector.size() == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

Integer integer = vector.firstElement();
vector.remove(integer);
System.out.println(Thread.currentThread().getName() + ",已取完数据。");
System.out.println("队列中还有:" + vector.size());
return integer;
}


public static void main(String[] args){
final SimpleQueue simpleQueue = new SimpleQueue();
new Thread(new Runnable() {

@Override
public void run() {
try {
while(true){
simpleQueue.get();
Thread.sleep(new Random().nextInt(1000));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();

new Thread(new Runnable() {
@Override
public void run() {
try {
while(true){
simpleQueue.put();
Thread.sleep(new Random().nextInt(1000));
}
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}).start();

}

}



[size=x-large][b]2、我们定义一个简单的队列。三个放数据的线程,三个取数据的线程。队列可以无限大,如果放数据的线程远多余取数据的线程,这样就会大大增加内存泄露的危险[/b][/size]
package com.zte;

import java.util.Random;


public class MitThreadBufferArraySimpleQueue {

Integer[] array = new Integer[20];
int putPostion;
int getPostion;
int count;
public synchronized void put(){
if(count == array.length) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + ",开始放数据。");
array[putPostion] = new Random().nextInt(1000);
putPostion ++;
count ++;
if(putPostion == array.length) putPostion = 0;
System.out.println(Thread.currentThread().getName() + ",已放完数据。");
System.out.println("队列中还有:" + count +"个对象");
this.notify(); //只是通知另外的线程你可以获得锁,如果本线程获取了锁,其他线程也是获取不到锁的
}

public synchronized Integer get(){
if(count == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

System.out.println(Thread.currentThread().getName() + ",开始取数据。");
Integer intObject = array[getPostion];
getPostion ++ ;
count--;
if(getPostion == array.length) getPostion = 0;

System.out.println(Thread.currentThread().getName() + ",已取完数据。");
System.out.println("队列中还有:" + count + "个对象");
this.notify();
return intObject;
}


public static void main(String[] args){
final MitThreadBufferArraySimpleQueue bufferArraySimpleQueue= new MitThreadBufferArraySimpleQueue();
for(int i=0 ; i<3;i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
while(true){
bufferArraySimpleQueue.get();
Thread.sleep(new Random().nextInt(1000));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}

for(int j=0 ; j<3;j++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
while(true){
bufferArraySimpleQueue.put();
Thread.sleep(new Random().nextInt(1000));
}
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}).start();
}
}

}


[size=x-large][b]3、定义一个带有缓冲区的队列,这样可以避免内存溢出。虽然避免了内存溢出问题,但拥塞现象严重[/b][/size]
package com.zte;

import java.util.Random;


public class MitThreadBufferArraySimpleQueue {

Integer[] array = new Integer[20];
int putPostion;
int getPostion;
int count;
public synchronized void put(){
if(count == array.length) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + ",开始放数据。");
array[putPostion] = new Random().nextInt(1000);
putPostion ++;
count ++;
if(putPostion == array.length) putPostion = 0;
System.out.println(Thread.currentThread().getName() + ",已放完数据。");
System.out.println("队列中还有:" + count +"个对象");
this.notify(); //只是通知另外的线程你可以获得锁,如果本线程获取了锁,其他线程也是获取不到锁的
}

public synchronized Integer get(){
if(count == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

System.out.println(Thread.currentThread().getName() + ",开始取数据。");
Integer intObject = array[getPostion];
getPostion ++ ;
count--;
if(getPostion == array.length) getPostion = 0;

System.out.println(Thread.currentThread().getName() + ",已取完数据。");
System.out.println("队列中还有:" + count + "个对象");
this.notify();
return intObject;
}


public static void main(String[] args){
final MitThreadBufferArraySimpleQueue bufferArraySimpleQueue= new MitThreadBufferArraySimpleQueue();
for(int i=0 ; i<3;i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
while(true){
bufferArraySimpleQueue.get();
Thread.sleep(new Random().nextInt(1000));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}

for(int j=0 ; j<3;j++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
while(true){
bufferArraySimpleQueue.put();
Thread.sleep(new Random().nextInt(1000));
}
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}).start();
}
}

}


[size=x-large][b]4、考虑带缓冲区的队列,启动多个线程存放数据,出现数据脏数据。[/b][/size]
package com.zte;

import java.util.Random;


public class ConditionMitThreadBufferArraySimpleQueue {

Integer[] array = new Integer[20];
int putPostion;
int getPostion;
int count;
public synchronized void put(){
if(count == array.length) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + ",开始放数据。");
array[putPostion] = new Random().nextInt(1000);
putPostion ++;
count ++;
if(putPostion == array.length) putPostion = 0;
System.out.println(Thread.currentThread().getName() + ",已放完数据。");
System.out.println("队列中还有:" + count +"个对象");
this.notify(); //只是通知另外的线程你可以获得锁,如果本线程获取了锁,其他线程也是获取不到锁的
}

public synchronized Integer get(){
if(count == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

System.out.println(Thread.currentThread().getName() + ",开始取数据。");
Integer intObject = array[getPostion];
getPostion ++ ;
count--;
if(getPostion == array.length) getPostion = 0;

System.out.println(Thread.currentThread().getName() + ",已取完数据。");
System.out.println("队列中还有:" + count + "个对象");
this.notify();
return intObject;
}


public static void main(String[] args){
final ConditionMitThreadBufferArraySimpleQueue bufferArraySimpleQueue= new ConditionMitThreadBufferArraySimpleQueue();
for(int i=0 ; i<3;i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
while(true){
bufferArraySimpleQueue.get();
Thread.sleep(new Random().nextInt(1000));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}

for(int j=0 ; j<3;j++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
while(true){
bufferArraySimpleQueue.put();
Thread.sleep(new Random().nextInt(1000));
}
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}).start();
}
}

}


运行部分结果:
队列中还有:-2个对象
Thread-0,开始取数据。
Thread-0,已取完数据。
队列中还有:-3个对象
Thread-1,开始取数据。
Thread-1,已取完数据。
队列中还有:-4个对象
Thread-5,开始放数据。
Thread-5,已放完数据。
队列中还有:-3个对象
Thread-4,开始放数据。
Thread-4,已放完数据。
队列中还有:-2个对象
Thread-3,开始放数据。
Thread-3,已放完数据。
队列中还有:-1个对象
Thread-0,开始取数据。
Thread-0,已取完数据。
队列中还有:-2个对象
Thread-2,开始取数据。
Thread-2,已取完数据。
队列中还有:-3个对象
Thread-0,开始取数据。
Thread-0,已取完数据。
队列中还有:-4个对象

[size=x-large][b]5、运用JAVA5中锁与Condition机制,完美解决问题[/b][/size]
package com.zte;

import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


public class BufferArraySimpleQueue {

Integer[] array = new Integer[20];
int putPostion;
int getPostion;
int count;
Lock lock = new ReentrantLock();
Condition readCondition = lock.newCondition();
Condition writeCondition = lock.newCondition();
public void put(){
lock.lock();
try{
if(count == array.length) {
try {
writeCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + ",开始放数据。");
array[putPostion] = new Random().nextInt(1000);
putPostion ++;
count ++;
if(putPostion == array.length) putPostion = 0;
System.out.println(Thread.currentThread().getName() + ",已放完数据。");
System.out.println("队列中还有:" + count +"个对象");
readCondition.signal(); //只是通知另外的线程你可以获得锁,如果本线程获取了锁,其他线程也是获取不到锁的
}finally {
lock.unlock();
}
}

public Integer get(){
lock.lock();
try{
if(count == 0) {
try {
readCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

System.out.println(Thread.currentThread().getName() + ",开始取数据。");
Integer intObject = array[getPostion];
getPostion ++ ;
count--;
if(getPostion == array.length) getPostion = 0;

System.out.println(Thread.currentThread().getName() + ",已取完数据。");
System.out.println("队列中还有:" + count + "个对象");
writeCondition.signal();
return intObject;
}finally{
lock.unlock();
}
}


public static void main(String[] args){
final BufferArraySimpleQueue bufferArraySimpleQueue= new BufferArraySimpleQueue();

new Thread(new Runnable() {
@Override
public void run() {
try {
while(true){
bufferArraySimpleQueue.get();
Thread.sleep(new Random().nextInt(1000));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();


new Thread(new Runnable() {
@Override
public void run() {
try {
while(true){
bufferArraySimpleQueue.put();
Thread.sleep(new Random().nextInt(500));
}
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}).start();

}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值