2012-03-04 99 views
2

对于Java而言,我非常失望,因为它不允许以下代码以并发方式移动。当没有同步时,两个线程更频繁地切换,但是当尝试访问同步方法时,在第二个线程获得锁之前,它将花费太长时间(如30秒),并且在第一个线程获得锁之前从第二个。什么编码可以照顾更好地共享锁:java中的线程/同步

public synchronized static void i() 
    { 

    System.out.println(Thread.currentThread().getName()); 

    } 
    public static void main(String[] f) 
    { 

    Thread t = new Thread(new Runnable(){ 
    public void run() 
    { 
     while(true) 
     i(); 
    }}); 
    t.setName("a: "); 
    Thread t2 = new Thread(new Runnable(){ 
    public void run() 
    { 
     while(true) 
     i(); 
     }}); 
     t2.setName("b: "); 
     t.start(); 
     t2.start(); 

    } 

回答

7

使用ReentrantLock将公平设置为true。

public static final ReentrantLock lock = new ReentrantLock(true); 
public static void i() 
{ 
    lock.lock(); 
    try { 
     System.out.println(Thread.currentThread().getName()); 

    } finally { 
     lock.unlock(); 
    } 
} 
+2

结合exabrial和Chikei的答案,你有正确的答案。出于执行原因指出的原因,公平不能被保证。但是在交错方面,我会和琪琪的建议一起使用一个锁定,以保证一定的公平性。如果你想'完美'交错,即线程B总是在线程A之后,线程A再次运行之前运行,那么你需要一个不同的锁定方案。 – brettw 2012-03-04 05:44:47

+0

非常感谢,这两种方法似乎工作得很好 – 2012-03-04 05:54:00

3

问题不是java,它是你的代码。锁合同的哪一部分意味着公平收购?简单地让一个现有的锁持有人继续是更快和更高效的;通常他们会完成工作并释放锁。你的程序应该对锁和线程交织的公平性做出0的假设。

如果你想要一个公平的交错,你不应该使用同步的方法。您需要创建一个私有对象,然后在该私有对象上手动使用wait()和notify()方法来强制交错,但即便如此,这也是一个假设:)为了确保您获得公平交错,您必须创建一个volatile条件变量指示谁来执行它。

+0

优秀的这项工作完美 – 2012-03-04 05:51:20