生产者消费者。看到自己代码联想的

   今天看了项目的源码。看到了每个方法都用synchronized 标注的方法,代码也懒得看了,幸好我们用户少,越来越少。。。。不需要那么高的并发。。。
   闲话不多说,早上说了观察者模式。突然想到了是不是可以用生产消费模式。一边做任务,一边处理任务,中间存任务状态,会不会耦合度少点,而且能做到线程安全(后来看了下,没有做到,必须在task 线程里面搞安全。回头多看看多线程和并发的知识)

上代码:

  1.message 类,就是生产者和消费者中间那个东西。一个生产一个消费。。。。。

 

package testProductIssue;

public class Message {

	private String msg;
	
	public Message(String msg){
		
		this.msg = msg;
	}
	
	public String getMsg(){
		return msg;
	}
}

 

   2.生产者:

package testProductIssue;

import java.util.concurrent.BlockingQueue;


public class Product implements Runnable{

	
	private BlockingQueue<Message> que ;
	
	public Product(BlockingQueue<Message> que){
		this.que = que;		
	}
	@Override
	public void run() {
		for(int i=0 ; i <10;i++){
			Message e = new Message("message:"+i);
	        try {
	        	
				que.put(e);
				System.out.println("this is P "+e.getMsg());
				Thread.sleep(1000);
			} catch (InterruptedException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}	
		}
		Message e = new Message("exit");
		try {
			que.put(e);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	
}

 3.消费者

package testProductIssue;

import java.util.concurrent.BlockingQueue;

public class Custom implements Runnable{

	private BlockingQueue<Message> que;
	
	public Custom(BlockingQueue<Message> que){
		this.que = que;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			Message msg ;
			//这里我看了下BlockingQueue的take方法,调用一次这个方法,这个queue里面的
			//东西就被取走了,所以就直接写在while里面了,这个如果设置成永远等下去,就等于
			//我上一个里面那个wait了。。感觉一个效果。
			while((msg=que.take()).getMsg()!="exit"){
				//先让他休息一下,要不可能那边放上去还没来得及打印到命令行这边就输出了,会造成困扰
				Thread.sleep(2000);
				System.out.println("this is C "+msg.getMsg());	
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

 4.测试类

package testProductIssue;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class TestIssue {
	public static void main(String[] args) throws InterruptedException {
		
		BlockingQueue<Message> msg = new ArrayBlockingQueue<Message>(5);		
		Thread pro = new Thread(new Product(msg));
		Thread cus = new Thread(new Custom(msg));
		pro.start();
		cus.start();
		pro.join();		
	}
}

 

这里的BlockingQueue要说一下,这是concurrent 包下面的一个接口,后面ArrayBlockingQueue是一个实现类,这个有什么特点呢。首先是线程安全的。而且有一个特点就是如果这个queue里面空的,则去操作会处于阻塞状态,如果这个queue是满的,添加操作处于阻塞状态,这里我设置queue的大小是5,下面我吧设置成2的输出到控制台 就能体会到这个阻塞的感觉了。。。

 

this is P message:0
this is P message:1
this is P message:2
this is C message:0 //取出一个数
this is P message:3 //才能放进去一个
this is C message:1 //取出一个
this is P message:4 //才能放进去一个
this is C message:2
this is P message:5
this is C message:3
this is P message:6
this is C message:4
this is P message:7
this is C message:5
this is P message:8
this is C message:6
this is P message:9
this is C message:7
this is C message:8
this is C message:9

 

 

然后 生产者消费者就是这样呀,两个线程 一个生产 一个消费,把东西放到超市(中间的那个queue) 然后各取所需。额貌似就这样,刚刚吃过晚饭,晚上回家继续研究,现在脑子里面啥都没有。。想起来再更新吧。。。。

 

当然,生产者消费者模式还有另一种实现,就是在中间缓存处不使用BlockingQueue 而是用其他的存储单位,这样的话,很容易造成线程不同步的问题,就是我们所说的多线程并发导致的数据不同步了,我网上看了下,可以用volatile关键字来定义容器中中得message,这样存取就不会乱掉。因为volatile是永远从内存中读得。现在想想这个关键字和 threadlocal完全是对立吧,一个是暴力同步内存中得。一个是保存对象副本。分场合来使用这两个东西吧。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值