2014-05-19 52 views
0

我想创建一个公平的锁,以便每个线程都被一个接一个地给予一个锁,而不管优先级如何。如何创建公平的锁解决java中的饥饿?

import java.util.concurrent.locks.ReentrantLock; 

public class StarvationRunnable implements Runnable { 

    private ReentrantLock lock = new ReentrantLock(true); 

    public void doLongTask() { 
     lock.lock(); 
     // to imitate long running task in critical section 
     for (int i = 0; i < 1000000000; i++) 
      ; 
     System.out.println(Thread.currentThread().getName() + " is running with priority " 
       + Thread.currentThread().getPriority() + " !"); 
     lock.unlock(); 
    } 

    @Override 
    public void run() { 
     for (;;) { 
      doLongTask(); 
     } 
    } 

    public static void main(String[] args) { 
     StarvationRunnable runnable = new StarvationRunnable(); 

     for (int i = 0; i < 4; i++) { 
      Thread thread = new Thread(runnable); 
      thread.setPriority(i == 3 ? Thread.MIN_PRIORITY : Thread.MAX_PRIORITY); 
      thread.start(); 
     } 
    } 
} 

所以我有4个主题。 3最大优先权和1最小优先权。我创建公平的锁

new ReentrantLock(true); 

当我运行这个演示时,它不给线程与最小优先级执行多次的线程与最大优先级。但我认为公平的锁只是为了这个。

如何正确使用公平锁?

+0

定义“公平锁” – alfasin

+0

这意味着每个线程都有一个锁顺序,使每个线程都可以运行同步方法的时间是相同的。 –

+2

@Volodia:那么这不是文档如何定义公平性:“如果设置为true,在争用情况下,锁定允许授予访问最长等待线程的权限。” –

回答

9

公平性与线程优先级无关。 The javadoc说:

该类的构造函数接受一个可选的公平参数。当设置为true时,在争用中,锁有利于授予对最长等待线程的访问权限。

另一方面,线程优先级暗示本地线程调度程序,以便给予高优先级线程的CPU时间比低优先级线程的CPU时间多,如果它们争夺CPU时间。

+0

当我运行演示时,优先级较低的线程不会像具有高优先级的线程一样多。但文档说'授予访问最长等待线程' –

+0

为什么公平锁不会以最小优先级锁定线程多次以最大优先级进行线程? –

+1

因为它符合文档所说的:将锁定给最长的等待线程。由于具有最高优先级的线程比具有最低优先级的线程具有更多的CPU访问权限,所以具有高优先级的线程更有可能实际执行请求锁定的指令。例如,最高优先级的线程可以被调度100次,并且在计划最小优先级线程之前运行100次长任务,从而有机会请求锁定。 –

0

我创建了一个使用java wait()notify()框架的示例实现。无论线程优先级如何,它都基于先来先服务(FCFS)提供锁定。

你可以看看公平锁定在实施https://github.com/nenapu/JavaLocks