Java并发编程之线程管理(基本线程同步5)

2.4 公平锁

      ReentrantLock和ReentrantReadWriteLock类的构造器允许名为公平的布尔参数,这个参数允许你控制这两个类的行为。false是默认值,这意味着以非公平模式运行。在这种模式下,当有些线程等待一个锁时,这个锁不得不选择它们中的一个去访问临界部分,它做出选择没有参考任何标准。true值称之为公平模式,当多个线程等待一个锁时,这个锁就会根据等待时间最长的线程作为其访问临界部分的线程。考虑到,先前解释过的行为仅仅被使用在lock()和unlock()方法中。

如果Lock接口使用的话,tryLock()方法不会让线程睡眠,公平锁属性不会影响它的功能。

下面,我创建一个实例来阐明这个原理。

定义Task类,这个类中执行有关的业务打印操作。

 

import java.util.concurrent.locks.Lock;
importjava.util.concurrent.locks.ReentrantLock;
 
public class Task {
    /**
     * Creates a lock to control the access to thequeue.
     * With the boolean attribute, we control thefairness of
     * the Lock
     */
    private finalLock queueLock=new ReentrantLock(true);
   
    /**
     * Method that prints the Job. The printing isdivided in two phase two
     * show how the fairness attribute affects theelection of the thread who
     * has the control of the lock
     * @param document The document to print
     */
    public voidprintTask(Object document){
        queueLock.lock();
       
        try {
            Long duration= (long) 1000;
            System.out.printf("%s: Task 1: Printing a task Job during %d seconds by creation order.\n",
                    Thread.currentThread().getName(),(duration/1000));
            Thread.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            queueLock.unlock();
        }
       
        queueLock.lock();
        try {
            Long duration=(long)(Math.random()*10000);
            System.out.printf("%s: Task 2: Printing a task Job during %d seconds\n",
                    Thread.currentThread().getName(),(duration/1000));
            Thread.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            queueLock.unlock();
        }
    }
}

定义Worker类,实现run()方法。

public class Worker implements Runnable{
 
    /**
     * The queue to send the documents
     */
    private Task printQueue;
   
    /**
     * Constructor of the class. Initializes theprint queue
     * @param printQueue the print queue to send the documents
     */
    public Worker(Task printQueue){
        this.printQueue=printQueue;
    }
   
    /**
     * Core method of the Job. Sends the documentto the queue
     */
    @Override
    public voidrun() {
        System.out.printf("%s: Going to print a job\n",
                          Thread.currentThread().getName());
        printQueue.printTask(new Object());
        System.out.printf("%s: The document has been printed\n",
                          Thread.currentThread().getName());    
    }
   
    public staticvoidmain(String []args){
             // Creates the print queue task
                Task printQueue=new Task();
               
                // Creates ten task and the Threads to run them
                Thread thread[]=new Thread[10];
                for (int i=0; i<10; i++){
                    thread[i]=new Thread(new Worker(printQueue),"Thread "+i);
                }
               
                // Launch a thread ever 0.1 seconds
                for (int i=0; i<10; i++){
                    thread[i].start();
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedExceptione) {
                        e.printStackTrace();
                    }
                }
    }
}


执行结果:

Thread0: Going to print a job
Thread0: Task 1: Printing a task Job during 1 seconds by creation order .
Thread1: Going to print a job
Thread2: Going to print a job
Thread3: Going to print a job
Thread4: Going to print a job
Thread5: Going to print a job
Thread6: Going to print a job
Thread7: Going to print a job
Thread8: Going to print a job
Thread9: Going to print a job
Thread1: Task 1: Printing a task Job during 1 seconds by creation order .
Thread2: Task 1: Printing a task Job during 1 seconds by creation order .
Thread3: Task 1: Printing a task Job during 1 seconds by creation order .
Thread4: Task 1: Printing a task Job during 1 seconds by creation order .
Thread5: Task 1: Printing a task Job during 1 seconds by creation order .
Thread6: Task 1: Printing a task Job during 1 seconds by creation order .
Thread7: Task 1: Printing a task Job during 1 seconds by creation order .
Thread8: Task 1: Printing a task Job during 1 seconds by creation order .
Thread9: Task 1: Printing a task Job during 1 seconds by creation order .
Thread0: Task 2: Printing a task Job during 0 seconds
Thread0: The document has been printed
Thread1: Task 2: Printing a task Job during 7 seconds
Thread1: The document has been printed
Thread2: Task 2: Printing a task Job during 1 seconds
Thread2: The document has been printed
Thread3: Task 2: Printing a task Job during 0 seconds
Thread3: The document has been printed
Thread4: Task 2: Printing a task Job during 8 seconds
Thread4: The document has been printed
Thread5: Task 2: Printing a task Job during 7 seconds
Thread5: The document has been printed
Thread6: Task 2: Printing a task Job during 1 seconds
Thread6: The document has been printed
Thread7: Task 2: Printing a task Job during 7 seconds
Thread7: The document has been printed
Thread8: Task 2: Printing a task Job during 8 seconds
Thread8: The document has been printed
Thread9: Task 2: Printing a task Job during 0 seconds
Thread 9: The document has been printed


Java并发编程之线程管理(基本线程同步5),布布扣,bubuko.com

Java并发编程之线程管理(基本线程同步5)

上一篇:python统计最近几天访问的网站次数


下一篇:C++构造函数、拷贝构造函数、赋值函数、析构函数在函数调用中的使用过程