`
晓伟哥
  • 浏览: 6234 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多
      回顾大学时期的java多线程学习,一直一知半解,工作后平时都是写些web前端代码,很少接触到服务器端编程,不用考虑线程安全性问题,多线程应用的可谓少之又少.
      还记得当初的生产者/消费者模型吗?生产者负责生产数据,消费者负责取走数据,生产者和消费者可以看做是两个线程,他们共享一个缓冲区,这两个线程相互协调工作,生产者第一次生产数据之前,消费者不能取数据,生产者每生产一数据,便通知消费者取走该数据,消费者取走完毕后,便通知生产者可以继续生产数据,如此反复,直至完成所有读写操作.这便涉及到了多线程的同步问题.
      实际生活中,我们遇到很多多线程同步的问题:QQ好友聊天;火车票销售/订购;网站服务器响应客户端等等.
      我们先定义要处理的资源(Box):
public class Box {
private int value;//要进行读写的值

private boolean available = false;//开关变量,true即表示value已生产,false即表示value已消费

public synchronized int get() {
while (available == false) {//Box无数据
try {
wait();// 交出对象锁,等待生产者写入数据
} catch (InterruptedException e) {
e.printStackTrace();
}
}
available = false;//开关变量取反,示意生产者可以生产数据
notifyAll();//唤醒线程池中所有阻塞线程
return value;
}

public synchronized void put(int value) {
while (available == true) {//Box有数据
try {
wait();// 交出对象锁,等待消费者取走数据
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.value = value;
available = true;//开关变量取反,示意消费者可以取走数据
notifyAll();//唤醒线程池中所有阻塞线程
}
}

      Box拥有供读写操作的value,生产者每生产(put())一数据(value),消费者便取走(get())一数据(value).



      线程--生产者:

public class Producer extends Thread {
private Box box;//要处理的资源

private String name;//生产者名称
//构造器
public Producer(Box box, String name) {
this.box = box;
this.name = name;
}

public void run() {
for (int i = 1; i < 6; i++) {
box.put(i);//写入数据i(即给box中的value设定初值)
System.out.println("Producer:" + name + "  " + "produced:" + i);//打印
try {
sleep((int) (Math.random() * 100));//强制睡眠,用以等待消费者取走数据
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}



      线程--消费者:

public class Consumer extends Thread {
private Box box;//要处理的资源

private String name;//消费者名称
//构造器
public Consumer(Box box, String name) {
this.box = box;
this.name = name;
}

public void run() {
int value = 0;
for (int i = 1; i < 6; i++) {
value = box.get();//取走数据(即获取box的value值)
System.out.println("Consumer:" + name + "  " + "consumed:" + value);
try {
sleep((int) (Math.random() * 100));//强制睡眠,用以等待生产者生产数据
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}
      给生产者和消费者都提供了一个Box属性,是因为他们处理的是同一资源Box,所以我们先new一个Box实例,然后分别对其进行操作:

      测试类:
public class ProducerConsumerTest {
public static void main(String[] args) {
Box box=new Box();//创建要处理的资源
Producer p=new Producer(box,"p");//构建一个生产者线程
Consumer c=new Consumer(box,"c");//构建一个消费者线程
p.start();//启动生产者线程
c.start();//启动消费者线程
}
}

      运行结果:
Producer:p  produced:1
Consumer:c  consumed:1
Producer:p  produced:2
Consumer:c  consumed:2
Producer:p  produced:3
Consumer:c  consumed:3
Producer:p  produced:4
Consumer:c  consumed:4
Producer:p  produced:5
Consumer:c  consumed:5

下接:java多线程入门二http://172672421-qq-com.iteye.com/admin/blogs/1128876
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics