2012-12-09 145 views
0

请不要把下面的问题看作是重复的问题..!关于同步的不同方法

我开发了一个让多线程按顺序依次运行的类。这个类的claimAccess函数和release Access函数之间的所有应用程序代码一次只能在一个线程中执行。所有其他线程将在队列中等待,直到前一个线程完成。现在请告知可以同样的事情由像执行人,循环障碍或倒计时锁也有一些其他的方式来实现.. !!请建议如何能够通过其他途径建立

import java.util.ArrayList; 
import java.util.List; 

public class AccessGate { 
    protected boolean shouldWait = false; 
    protected final List waitThreadQueue = new ArrayList(); 

    /** 
    * For a thread to determine if it should wait. It it is, the thread will 
    * wait until notified. 
    * 
    */ 
    public void claimAccess() { 
     final Thread thread = getWaitThread(); 
     if (thread != null) { 
      // let the thread wait untill notified 
      synchronized (thread) { 
       try { 
        thread.wait(); 
       } catch (InterruptedException exp) { 
       } 
      } 
     } 
    } 

    /** 
    * For a thread to determine if it should wait. It it is, the thread will be 
    * put into the waitThreadQueue to wait. 
    * 
    */ 
    private synchronized Thread getWaitThread() { 
     Thread thread = null; 
     if (shouldWait || !waitThreadQueue.isEmpty()) { 
      thread = Thread.currentThread(); 
      waitThreadQueue.add(thread); 
     } 
     shouldWait = true; 
     return thread; 
    } 

    /** 
    * Release the thread in the first position of the waitThreadQueue. 
    * 
    */ 
    public synchronized void releaseAccess() { 
     if (waitThreadQueue.isEmpty()) { 
      shouldWait = false; 
     } else { 
      shouldWait = true; 
      // give the claimAccess function a little time to complete 
      try { 
       Thread.sleep(10); 
      } catch (InterruptedException exp) { 
      } 

      // release the waiting thread 
      final Thread thread = (Thread) waitThreadQueue.remove(0); 
      synchronized (thread) { 
       thread.notifyAll(); 
      } 
     } 
    } 
} 
+0

排序的任务很重要吗? –

+0

@NarendraPathai是啊必须维护订单 – user1881169

+0

'Executors.newSingleThreadExecutor()'呢? –

回答

2

这是由ExecutorService

手段

Executors.singleThreadExecutor()将一次执行一项任务,并将按顺序执行。

创建一个使用单个worker线程的 无界队列操作Executor。 (然而,注意,如果此单个线程关闭之前执行期间终止 由于故障,一个新的将 如果需要的话,执行后续任务取而代之。)任务是 保证执行依次,且无超过一个任务将在任何给定时间处于活动状态 。

+0

你可以请发布更新的代码,因为我已经做了这些将有助于更多的理解,谢谢 – user1881169

+1

@ user1881169你应该先自己尝试,然后如果有问题,你总是可以再问一次。 :)我们在这里帮助。 –

+0

谢谢,但我无法实现,如果你可以请发布更新的代码,这将是一个很大的帮助,在此先感谢 – user1881169

2

是的,有更简单的方法来做到这一点。非常简单的是只使用一个显示器,无需等待,睡觉,或任何其他的恶作剧:

// somewhere visible 
public final Object accessGate = new Object(); 

// in your application code 
synchronized (accessGate) { 
    // this block will be executed only in one thread at one time 
} 

Java的内置显示器提供非常需要的语义。唯一的问题是线程获得锁的顺序不能保证;这取决于底层操作系统如何处理锁的排序(信号量或互斥锁或其他)。操作系统可以很好地保证你所需要的行为,但这通常不是可移植的。

如果您需要订购的便携式保证,您有几个选择。最明显的是ReentrantLock公平设置为true:

// somewhere visible 
public final Lock accessGate = new ReentrantLock(true); 

// in your application code 
accessGate.lock(); 
try { 
    // this block will be executed only in one thread at one time 
} 
finally { 
    accessGate.unlock(); 
} 

另一个是Semaphore与单个许可证和公平设置为true:

// somewhere visible 
public final Semaphore accessGate = new Semaphore(1, true); 

// in your application code 
accessGate.acquire(); 
try { 
    // this block will be executed only in one thread at one time 
} 
finally { 
    accessGate.release(); 
} 

这两个具有非常相似的行为。

+0

@ TomAnderson ..感谢了很多,你提出的两种方法真的很有帮助,你可以请发布完整的更新代码,因为我已经做了......这将有助于更多地了解 – user1881169

+0

你能请发布完整的代码,谢谢 – user1881169

+0

上面的代码不会保证订购!但问题提到订单将保留 –