zoukankan      html  css  js  c++  java
  • Java并发编程Semaphore

    信号量

    信号量类Semaphore,用来保护对唯一共享资源的访问。一个简单的打印队列,并发任务进行打印,加入信号量同时之能有一个线程进行打印任务 。

    import java.util.concurrent.Semaphore;
    
    public class PrintQueue {
    	public PrintQueue() {
    
    		semaphore = new Semaphore(1,true);
    	}
    
    	private final Semaphore semaphore;
    
    	public void printJob(Object document) {
    		try {
    			semaphore.acquire();
    
    			long duration = (long) (Math.random() * 10);
    
    			System.out.println("执行打印"+Thread.currentThread().getName() + "花费时间"+ duration+ "秒");
    			Thread.sleep(duration);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}finally{
    			semaphore.release();
    		}
    	}
    }
    
    
    public class Job  implements Runnable{
    
    	private PrintQueue printQueue;
    	
    	public Job(PrintQueue printQueue){
    		
    		this.printQueue=printQueue;
    	}
    	@Override
    	public void run() {
    		printQueue.printJob(new Object());
    		System.out.println("文档被打印"+Thread.currentThread().getName());
    	}
    }
    
    public class Main {
    	public static void main(String[] args) {
    		PrintQueue p = new PrintQueue();
    		Thread thread[] = new Thread[10];
    		for (int i = 0; i <thread.length; i++) {
    			thread[i]=new Thread(new Job(p),"Thread"+i);
    		}
    		for (int i = 0; i < thread.length; i++) {
    			thread[i].start();
    		}
    	}
    }
    ----------------------输出结果 ---------------------------
    执行打印Thread0花费时间9秒
    文档被打印Thread0
    执行打印Thread3花费时间9秒
    文档被打印Thread3
    执行打印Thread2花费时间6秒
    文档被打印Thread2
    执行打印Thread1花费时间4秒
    文档被打印Thread1
    执行打印Thread5花费时间6秒
    文档被打印Thread5
    执行打印Thread7花费时间3秒
    文档被打印Thread7
    执行打印Thread9花费时间8秒
    文档被打印Thread9
    执行打印Thread8花费时间0秒
    文档被打印Thread8
    执行打印Thread6花费时间8秒
    文档被打印Thread6
    执行打印Thread4花费时间7秒
    文档被打印Thread4
    
    
    如上声明一个打印队列,构造器初始化信号量对象来保护对打印队列的访问。semaphore.acquire();获取信号量,最后semaphore.release();用来释放。启动10个线程进行打印的操作,第一个获得信号量的线程将能访问临界区,其余的线程将被信号量阻塞,直到信号量的释放。信号量被释放后,将选择一个正在等待的线程并且允许它访问临界区。

    简单代码分析

    
        根据boolean fair ,来构建公平和非公平的信号量
        /**
         * Creates a {@code Semaphore} with the given number of
         * permits and the given fairness setting.
         *
         * @param permits the initial number of permits available.
         *        This value may be negative, in which case releases
         *        must occur before any acquires will be granted.
         * @param fair {@code true} if this semaphore will guarantee
         *        first-in first-out granting of permits under contention,
         *        else {@code false}
         */
        public Semaphore(int permits, boolean fair) {
            sync = (fair)? new FairSync(permits) : new NonfairSync(permits);
        }
    
        FairSync 和 NonfairSync 继承Sync 类,然而Sync 类继承 AbstractQueuedSynchronizer
       /**
         * Synchronization implementation for semaphore.  Uses AQS state
         * to represent permits. Subclassed into fair and nonfair
         * versions.
         */
        abstract static class Sync extends AbstractQueuedSynchronizer {
            private static final long serialVersionUID = 1192457210091910933L;
    
            Sync(int permits) {
                setState(permits);
            }
    
            final int getPermits() {
                return getState();
            }
    
            final int nonfairTryAcquireShared(int acquires) {
                for (;;) {
                    int available = getState();
                    int remaining = available - acquires;
                    if (remaining < 0 ||
                        compareAndSetState(available, remaining))
                        return remaining;
                }
            }
    
            protected final boolean tryReleaseShared(int releases) {
                for (;;) {
                    int p = getState();
                    if (compareAndSetState(p, p + releases))
                        return true;
                }
            }
    
            final void reducePermits(int reductions) {
                for (;;) {
                    int current = getState();
                    int next = current - reductions;
                    if (compareAndSetState(current, next))
                        return;
                }
            }
    
            final int drainPermits() {
                for (;;) {
                    int current = getState();
                    if (current == 0 || compareAndSetState(current, 0))
                        return current;
                }
            }
        }
    
    
    

    参考文献

    Java并发编程
    AbstractQueuedSynchronizer

  • 相关阅读:
    tensorflow 安装 CentOS查看CPU、内存、版本等系统信息
    tensorflow 安装 centos下显卡驱动和cuda安装
    tensorflow 安装: could no t load dynamic library 'cudart64_101.dll'; dlerror: cudart64_101.dll not found
    安装tensorflow 官网手册
    安装 TensorFlow时:Cannot uninstall 'enum34'. It is a distutils installed project and thus we ca...
    python pip 和pip3区别
    安装TensorFlow报错Memoryerror
    使用清华开源镜像安装tensorflow
    centos7(python2.7) 安装tensorflow+keras过程
    JavaWeb核心之Servlet
  • 原文地址:https://www.cnblogs.com/tonyY/p/5088832.html
Copyright © 2011-2022 走看看