JAVA多线程之生产者消费者问题&&读写锁问题
2015-11-14 15:43
423 查看
1、生产者消费者问题
生产者-消费者(producer-consumer)问题,也称作有界缓冲区(bounded-buffer)问题,两个进程共享一个公共的固定大小的缓冲区。其中一个是生产者,用于将消息放入缓冲区;另外一个是消费者,用于从缓冲区中取出消息。问题出现在当缓冲区已经满了,而此时生产者还想向其中放入一个新的数据项的情形,其解决方法是让生产者此时进行休眠,等待消费者从缓冲区中取走了一个或者多个数据后再去唤醒它。同样地,当缓冲区已经空了,而消费者还想去取消息,此时也可以让消费者进行休眠,等待生产者放入一个或者多个数据时再唤醒它。
1.1 首先定义公共资源类,其中的变量number是保存的公共数据。并且定义两个方法,增加number的值和减少number的值。由于多线程的原因,必须加上synchronized关键字,注意while判断的条件。
运行结果如下:
2、读写锁问题
2.1 数据类 Data.java
2.2 测试类 Test.java
生产者-消费者(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(); } }
相关文章推荐
- SpringMVC中@ResponseBody中文乱码
- JAVA使用for循环打印三角形
- 获取图片大小 java
- Java基础
- Java 枚举 String-String
- (转) java排列组合算法(n选m)
- Java项目发布之基础知识准备
- spring 时间组件
- Caused by: java.io.FileNotFoundException: dbcpconfig.properties (No such file or directory)
- 自定义泛型JAVA_116-118
- 10009---JavaWeb基础--GenericServlet
- Eclipse CDT 代码首次编译通过,第二次编译提示error: ld returned 1 exit status
- 进程调度算法模拟,用动态优先数及时间片轮转法实现进程调度_Java语言模拟实现
- 把一个10进制的数转换成16进制数(java)
- 关于Java String 的些总结
- 7、SpringMVC源码分析(2):分析HandlerAdapter.handle方法,了解handler方法的调用细节以及@ModelAttribute注解
- spring mvc 报错 expected at least 1 bean which qualifies as autowire candidate for this depend
- springmvc环境的搭建
- Java中关于HashMap的使用和遍历
- java中正则表达式