java semaphore

java基于semaphore方式实现对资源的并发访问,也是多线程同步的一种方式,它一般是用于实现对多个资源副本的并发访问控制,而synchronized,lock等同步方式不同则用于针对一个资源的并发访问控制,也就是说资源只允许一个线程同时访问,而semaphore则可以控制某几个线程同时访问资源。
当然semaphore它也有一个变种,即二进制信号量,它的作用实际上和synchronized和lock就差不多了,二进制信号量也是限制资源只允许一个线程同时访问。
具体的内容可以参考下面的例子。

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\n",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\n",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\n",Thread. currentThread().getName());
        printQueue.printJob(new Object());
        System.out.printf("%s: The document has been printed\n",Thread.currentThread().getName());
    }

}

你可能感兴趣的:(Java,线程)