2012-01-31 44 views
0

我正在练习java线程,我很困惑与锁定机制, 我想实现的是当一个线程需要很多时间来执行代码块其锁定它已经收购了,其他线程应该只是不能等待,去为其他条件,线程等待一个锁,当它不应该

这是我的代码如下

import java.util.concurrent.locks.*; 
    import java.util.concurrent.*; 

    class MySharedData{ 
    private volatile boolean bFlag; 
    private int counter=1; 
    public void abuseIt() throws Exception{ 
    while(!bFlag){ 
      System.out.println(" THREAD "+Thread.currentThread().getName()+" WITH COUNTER "+counter); 
      counter++; 
      Thread.sleep(1000); 
      if(counter > 20){ 
       bFlag=true; 
      } 
     } 
    } 
    } 


    class RequesterThree implements Runnable{ 
    private Lock lock; 
    RequesterThree(){ 
    lock = new ReentrantLock(); 
    } 
    @Override 
    public void run(){ 
    MySharedData myShared = null; 
    try{ 
      myShared = new MySharedData(); 
      if(lock.tryLock(250,TimeUnit.MILLISECONDS)){    
       myShared.abuseIt(); 
      }else{ 
       System.out.println(Thread.currentThread().getName()+": SHARED DATA IS NON-ACCESSIBLE !!!!"); 
      }   
     }catch(Exception e){ 
      System.out.println(e); 
     }finally{ 
      lock.unlock(); 
     }  
    } 
    } 

    public class Ex03{ 
     public static void main(String [] args){ 
     Thread[] requests = new Thread[]{ 
      new Thread(new RequesterThree(),"MICHEAL"), 
      new Thread(new RequesterThree(),"SHAWN"), 
      new Thread(new RequesterThree(),"JOHN"), 
      new Thread(new RequesterThree(),"TRON"), 
      new Thread(new RequesterThree(),"FINCH") 
     }; 
     for(int x=0; x < requests.length; x++){ 
      requests[x].start(); 
     } 
    } 
    } 

但这里所有五个线程等待锁,没有单个线程在其他条件下打印SOP,

我所期待的,

当线程T1启动时,它获取锁,并执行abuseIt()方法,它睡觉1秒,

现在是线程T2应该等待锁获得免费仅为250毫秒为单位,但T1是任何如何等待1秒,所以T2应在run方法执行else条件,

我怎样才能做到这一点,

+0

修正你的代码,这样,除非它锁定它,它不会解除锁定。另外,我没有看到你初始化'bFlag'的地方。 – 2012-01-31 10:05:47

回答

1

在你的代码,每个RequesterThree对象有一个单独的锁,所以它们之间没有同步。

此外,每个线程在其自己的专用实例MySharedData上调用myShared.abuseIt()

要解决:

private static final Lock lock = new ReentrantLock(); 
private static final MySharedData myShared = new MySharedData(); 

此外,删除构造和变化run()方法:

@Override 
public void run(){ 
try{ 
     if(lock.tryLock(250,TimeUnit.MILLISECONDS)){    

最后,你的代码可以调用unlock()即使tryLock()没有成功。这需要修复。

+0

将main方法中的所有线程传递给RequesterThree对象怎么样? – 2012-01-31 11:38:38

1

让你的锁场最终静态

... 
class RequesterThree implements Runnable{ 
    private static final Lock lock = new ReentrantLock(); 
    RequesterThree(){ 

    } 
... 
相关问题