线程不应该等待锁定

时间:2012-01-31 10:02:15

标签: java multithreading

我在java线程上练习,我对Locking机制感到困惑, 我想要实现的是当一个线程花费很多时间来执行一个已经获得锁定的代码块时,另一个线程应该等不及等待其他条件,

这是我的代码如下

    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();
        }   
    }
    }

但是这里所有五个线程都在等待锁定,并且没有一个线程在else条件下打印SOP,

我期待的是,

当线程T1启动时,它获取锁定,并执行abuseIt()方法,在那里睡眠1秒,

现在线程T2应该等待锁定才能获得250毫秒的空闲,但是T1是等待1秒的任何时间,所以T2应该在run方法中执行else条件,

我如何实现这一目标,

2 个答案:

答案 0 :(得分:1)

在您的代码中,每个RequesterThree对象都有一个单独的锁,因此它们之间没有同步。

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

修复:

 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()。这需要修复。

答案 1 :(得分:1)

让你的锁定场最终静止

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

    }  
...