您的位置:首页 > 编程语言 > Java开发

JAVA多线程之生产者消费者问题&&读写锁问题

2015-11-14 15:43 423 查看
1、生产者消费者问题
生产者-消费者(producer-consumer)问题,也称作有界缓冲区(bounded-buffer)问题,两个进程共享一个公共的固定大小的缓冲区。其中一个是生产者,用于将消息放入缓冲区;另外一个是消费者,用于从缓冲区中取出消息。问题出现在当缓冲区已经满了,而此时生产者还想向其中放入一个新的数据项的情形,其解决方法是让生产者此时进行休眠,等待消费者从缓冲区中取走了一个或者多个数据后再去唤醒它。同样地,当缓冲区已经空了,而消费者还想去取消息,此时也可以让消费者进行休眠,等待生产者放入一个或者多个数据时再唤醒它。

1.1 首先定义公共资源类,其中的变量number是保存的公共数据。并且定义两个方法,增加number的值和减少number的值。由于多线程的原因,必须加上synchronized关键字,注意while判断的条件。
package Productor_Consumer;

public class Resource {
private int resnum = 0;
public synchronized void product(){
while(resnum != 0){
try {
//如果资源数不等于0,一直等到资源数为0,再生产
wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
resnum++;
System.out.println(Thread.currentThread().getName()+"生产完成,资源数为:"+resnum);
notify();
}
public synchronized void decrease(){
while(resnum == 0){
try{
//如果资源数为0;等待,直到资源数不为0,再消费
wait();
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
resnum--;
System.out.println(Thread.currentThread().getName()+"消费产品,资源数为:"+resnum);
notify();
}

}
1.2 生产者消费者线程

package Productor_Consumer;

public class Productor extends Thread{
public Resource res;
public Productor(Resource res){
this.res = res;
}
@Override
public void run(){
for(int i=0; i<10; i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
res.product();

}
}

}
<pre name="code" class="java">package Productor_Consumer;

public class Consumer extends Thread{
public Resource res;
public Consumer(Resource res){
this.res = res;
}
@Override
public void run(){
for(int i =0; i<10; i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
res.decrease();
}
}

}
1.3 测试类


<pre name="code" class="java">package Productor_Consumer;

public class Test {

public static void main(String[] args) {
Resource resource = new Resource();
new Productor(resource).start();
new Consumer(resource).start();
new Productor(resource).start();
new Consumer(resource).start();
}

}


运行结果如下:

Thread-0生产完成,资源数为:1
Thread-1消费产品,资源数为:0
Thread-2生产完成,资源数为:1
Thread-3消费产品,资源数为:0
Thread-2生产完成,资源数为:1
Thread-1消费产品,资源数为:0
Thread-0生产完成,资源数为:1
Thread-3消费产品,资源数为:0
Thread-2生产完成,资源数为:1
Thread-1消费产品,资源数为:0
Thread-0生产完成,资源数为:1
Thread-3消费产品,资源数为:0
Thread-2生产完成,资源数为:1
Thread-1消费产品,资源数为:0
Thread-0生产完成,资源数为:1

2、读写锁问题
2.1 数据类 Data.java
package ReadWriteLock;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Data {
private static String data = "Hello";
ReadWriteLock lock = new ReentrantReadWriteLock();
public String getData(){
lock.readLock().lock();
System.out.println(Thread.currentThread().getName()+"开始读取数据!");
try{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return data;
}finally{
System.out.println(Thread.currentThread().getName()+"数据读取完成!");
lock.readLock().unlock();
}
}
public void set(String data){
lock.writeLock().lock();
System.out.println(Thread.currentThread().getName()+"开始写入数据");
try{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"写入数据为:"+data);
this.data = this.data+data;
}finally{
System.out.println(Thread.currentThread().getName()+"数据写入完成");
lock.writeLock().unlock();
}
}

}


2.2 测试类 Test.java
package ReadWriteLock;

public class Test {

public static void main(String[] args) {
new Thread(){
public void run(){
for(int i=0; i<10; i++)
System.out.println(Thread.currentThread().getName()+"读取到的数据为:"+new Data().getData());

}
}.start();

new Thread(){
public void run(){
for(int i=0; i<10; i++){
new Data().set(String.valueOf(i));
}
}
}.start();

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: