java semaphore

6830 ワード

JAvaはsemaphore方式に基づいてリソースへの同時アクセスを実現し、マルチスレッド同期の一種でもある.一般的には複数のリソースコピーへの同時アクセス制御を実現するために用いられるが、synchronized、lockなどの同期方式は1つのリソースに対する同時アクセス制御に用いられる.つまり、リソースは1つのスレッドのみが同時にアクセスできる.semaphoreは、いくつかのスレッドを制御してリソースに同時にアクセスできます.もちろんsemaphoreにも変種があります.すなわち、バイナリ信号量です.実際にはsynchronizedとlockと差が少なく、バイナリ信号量もリソースが1つのスレッドだけで同時にアクセスできることを制限します.具体的な内容は以下の例を参考にすることができる.
package com.basic.thread;

import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class BasicSemaphore {
    public static void main(String args[]) {
        PrintQueueSem pq = new PrintQueueSem();
        Thread thread[] = new Thread[10];

        for (int i=0; i<10; i++) {
            thread[i] = new Thread(new Job(pq), "Thread" + i);
        }

        for (int i=0; i<10; i++) {
            thread[i].start();
        }
    }
}

class PrintQueue {
    private final Semaphore semaphore;

    public PrintQueue() {
        semaphore = new Semaphore(1);
    }

    public void printJob(Object doc) {
        try {
            semaphore.acquire();
            long duration = (long) (Math.random()*10);
            System.out.printf("%s: PrintQueue: Printing a Job during %d seconds
"
,Thread.currentThread().getName(),duration); Thread.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } } } class PrintQueueSem { private boolean freePrinters[]; private Lock lockPrinter; private final Semaphore semaphore; public PrintQueueSem() { semaphore = new Semaphore(3); freePrinters = new boolean[3]; for (int i = 0; i < 3; i++) { freePrinters[i] = true; } lockPrinter = new ReentrantLock(); } public void printJob(Object obj) { try { semaphore.acquire(); int assignedPrinter = getPrinter(); long duration = (long) (Math.random()*10); System.out.printf("%s: PrintQueue: Printing a Job in Printer%d during %d seconds
"
,Thread.currentThread().getName(), assignedPrinter,duration); Thread.sleep(duration); freePrinters[assignedPrinter] = true; } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } } private int getPrinter() { int ret = -1; try { lockPrinter.lock(); for (int i=0; iif (freePrinters[i]) { ret = i; freePrinters[i]=false; break; } } } catch (Exception e) { e.printStackTrace(); } finally { lockPrinter.unlock(); } return ret; } } class Job implements Runnable { /** private PrintQueue printQueue; public Job(PrintQueueSem pq) { this.printQueue = pq; } */ private PrintQueueSem printQueue; public Job(PrintQueueSem pq) { this.printQueue = pq; } @Override public void run() { System.out.printf("%s: Going to print a job
"
,Thread. currentThread().getName()); printQueue.printJob(new Object()); System.out.printf("%s: The document has been printed
"
,Thread.currentThread().getName()); } }