java.util.concurrent.Semaphore

信号量

一、问题描述 生产者-消费者问题是一个经典的进程同步问题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制。 他要求设计在同一个进程地址空间内执行的两个线程。 生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。 消费者线程从缓冲区中获得物品,然后释放缓冲区。 当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。 当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。

package examples.ch06.example01;

import java.util.LinkedList;
import java.util.concurrent.Semaphore;

/**
 * @author Administrator
 * 
 */
public class TestSemaphore {

	static Warehouse buffer = new Warehouse();

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		for (int i = 0; i < 10; i++) {
			Thread producer = new Thread(new Producer());
			producer.start();
		}
		for (int i = 0; i < 15; i++) {
			Thread consumer = new Thread(new Consumer());
			consumer.start();
		}
	}

	static class Producer implements Runnable {
		static int i = 0;

		@Override
		public void run() {
			while (true) {
				i++;
				try {
					buffer.put(i);
					System.out.println("put: " + i+" in thread: "+Thread.currentThread());
					Thread.sleep(500);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

		}

	}

	static class Consumer implements Runnable {

		@Override
		public void run() {
			while (true) {
				try {
					Object x = buffer.take();
					System.out.println("take: " + x+" in thread: "+Thread.currentThread());
					Thread.sleep(1000);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

		}

	}

	static class Warehouse {

		// 非满锁,表示如果小于10,则说明仓库没有满。
		final Semaphore notFull = new Semaphore(5);

		// 非空锁,表示如果大于0,则说明仓库不为空。
		final Semaphore notEmpty = new Semaphore(5);

		// 核心锁,与lock()、unlock()相似
		final Semaphore mutex = new Semaphore(1);

		final LinkedList<Object> items = new LinkedList<Object>();

		/**
		 * 添置商品到仓库中
		 * 
		 * @param x
		 * @throws Exception
		 */
		public void put(Object x) throws Exception {
			notFull.acquire();
			System.out.println();
			mutex.acquire();
			System.out.println("notFull: " + notFull.availablePermits()
					+ " mutex: " + mutex.availablePermits());
			try {
				items.addLast(x);
			} finally {
				mutex.release();
				notFull.release();
			}
		}

		public Object take() throws Exception {
			notEmpty.acquire();
			mutex.acquire();
			System.out.println("notEmpty: " + notEmpty.availablePermits()
					+ " mutex: " + mutex.availablePermits());
			try {
				// 减少库存
				if (!items.isEmpty()) {
					return items.remove();
				}
				return null;
			} finally {
				mutex.release();
				notEmpty.release();
			}
		}

	}

}
 

f

经验分享 程序员 微信小程序 职场和发展