博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java实现信号量
阅读量:5901 次
发布时间:2019-06-19

本文共 4907 字,大约阅读时间需要 16 分钟。

       本文介绍的Semaphore实现基于synchronized,wait()和notify/notifyAll(),这是java并发包之前的典型实现方式.在eclipse的源码中可以找到不少这样的案例,下文中也会把eclipse中的几个实现类作为案例以分析之.

       注,这里介绍的信号量实现是基于java语言机制,用于实现多线程间的同步操作,所以对S,P(S),V(S)等概念的介绍将结合本文内容,做合适的调整,读者可阅读操作系统相关书籍的信号量章节获取标准定义.

 

*本文内容

---信号量简介

---典型案例

 

*Semaphore概述

---通常把一个非负整数称为Semaphore,表示为S.

S可以理解为可用的资源数量.这里不涉及进程问题,所以就假定S>=0.

---S实现的同步机制表示为PV原语操作

P(S):若S=0,线程进入等待队列;否则,—S;

V(S):++S,唤醒处于等待中的线程.

(注,P是荷兰语的Passeren,相当于英文的pass, V是荷兰语的Verhoog,相当于英文中的incremnet).

 

*案例

1)典型实现

这段程序源自ibm的一本并发书籍,实现了计数信号量{S|S∈{0,N}}和二元信号量(S={0,1})

public abstract class Semaphore {	private int value = 0;	public Semaphore() {	}	public Semaphore(int initial) {		if (initial >= 0)			value = initial;		else			throw new IllegalArgumentException("initial < 0");	}	public final synchronized void P() throws InterruptedException {		while (value == 0)			wait();		value--;	}	protected final synchronized void Vc() {		value++;		notifyAll();	}	protected final synchronized void Vb() {		value++;		notifyAll();		if (value > 1)			value = 1;	}	public abstract void V();	public String toString() {		return ".value=" + value;	}}public final class BinarySemaphore extends Semaphore {	public BinarySemaphore() {		super();	}	public BinarySemaphore(int initial) {		super(initial);		if (initial > 1)			throw new IllegalArgumentException("initial > 1");	}	public final synchronized void V() {		super.Vb();	}}public final class CountingSemaphore extends Semaphore {	public CountingSemaphore() {		super();	}	public CountingSemaphore(int initial) {		super(initial);	}	public final synchronized void V() {		super.Vc();	}}

2)实现读写锁

eclipse使用它,解决日志操作相关类在map,数组中的同步问题.

/******************************************************************************* * Copyright (c) 2008, 2011 IBM Corporation and others * All rights reserved. This program and the accompanying materials are made * available under the terms of the Eclipse Public License v1.0 which * accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html ******************************************************************************/package org.eclipse.equinox.log.internal;public class BasicReadWriteLock {	private int currentReaders = 0;	private int writersWaiting = 0;	private boolean writing = false;	public synchronized void readLock() {		while (writing || writersWaiting != 0) {			try {				wait();			} catch (InterruptedException e) {				// reset interrupted state but keep waiting				Thread.currentThread().interrupt();			}		}		currentReaders++;	}	public synchronized void readUnlock() {		currentReaders--;		notifyAll();	}	public synchronized void writeLock() {		writersWaiting++;		while (writing || currentReaders != 0) {			try {				wait();			} catch (InterruptedException e) {				// reset interrupted state but keep waiting				Thread.currentThread().interrupt();			}		}		writersWaiting--;		writing = true;	}	public synchronized void writeUnlock() {		writing = false;		notifyAll();	}}

3)延迟信号量

这个信号量的亮点在acquire(long delay).

/******************************************************************************* * Copyright (c) 2003, 2006 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: *     IBM Corporation - initial API and implementation *******************************************************************************/package org.eclipse.core.runtime.internal.adaptor;/** * Internal class. */public class Semaphore {	protected long notifications;	public Semaphore(int count) {		notifications = count;	}	/**	 * Attempts to acquire this semaphore.  Returns only when the semaphore has been acquired.	 */	public synchronized void acquire() {		while (true) {			if (notifications > 0) {				notifications--;				return;			}			try {				wait();			} catch (InterruptedException e) {				//Ignore			}		}	}	/**	 * Attempts to acquire this semaphore.  Returns true if it was successfully acquired,	 * and false otherwise.	 */	public synchronized boolean acquire(long delay) { //若传入负数,用于判断是否资源已被占		long start = System.currentTimeMillis();		long timeLeft = delay;		while (true) {			if (notifications > 0) {				notifications--;				return true;			}			if (timeLeft <= 0)        //在延迟后不再继续尝试获取锁				return false;			try {				wait(timeLeft);			} catch (InterruptedException e) {				//Ignore			}			timeLeft = start + delay - System.currentTimeMillis();		}	}	public synchronized void release() {		notifications++;		notifyAll();	}	// for debug only	public String toString() {		return "Semaphore(" + notifications + ")"; //$NON-NLS-1$ //$NON-NLS-2$	}

 

 

*总结

---通过java的对象锁,wait/notify机制模拟的信号量,可以呈现多种形态以应对各种的互斥需求.

---本文给出的例子,具有普遍的适用性.在实践中,咱们可以根据需求定制各种信号量实现.

---jdk1.5提供了Semaphore的另一种实现机制.

转载于:https://www.cnblogs.com/balaamwe/archive/2012/07/27/2612210.html

你可能感兴趣的文章
Ad Hoc
查看>>
Serializable Clonable
查看>>
《mysql数据库备份小脚本》(转)
查看>>
10秒钟完成MySQL数据库结构对比
查看>>
VDI序曲一 服务器虚拟化
查看>>
Forrester:2011年Q2数据库审计与实时保护市场分析报告
查看>>
美国国防部的LPS便携安全系统
查看>>
工作与生活平衡 -- 别跟自己较劲
查看>>
如何做好基层技术管理工作?
查看>>
大数据和云计算的鞍马情-【软件和信息服务】2014.08
查看>>
苏州FreeNAS+ESXi5数据恢复案例
查看>>
rsync重要功能特性02
查看>>
WCF宿主与服务托管
查看>>
案例导学《系统集成项目管理工程师考试考点分析与真题详解》
查看>>
关于SIEM和LM产品形态的小调查
查看>>
【思想篇】要感谢那些曾经慢待你的人
查看>>
学习沟通技巧--- SOFTEN法则与SOLER法则
查看>>
Windows Server 2008 将计算机加入到指定组织单元
查看>>
Ubuntu系统(六)-安装SSH服务端和客户端及Telnet
查看>>
MongoDB经典面试题集锦
查看>>