没错,我又开了个坑。这次的问题是 按顺序打印。大意就是有 one two three 三个线程同时在跑,一定要让 two 在 one 后面、three 在 two 后面执行。
题目
本来觉得用 Go 的 channel 应该是最好写的。
1 2
var oneDone chan//one 结束就 oneDone <- var twoDone chan//two 结束就 twoDone <-
可惜并没有 Go。所以,要不 Java ?
阻塞队列
那么要做到和 channel 类似的效果,首先就是确保 BlockingQueue 能在没有元素 pop 的时候能阻塞。查一下 api 有个 take () 方法
1 2 3 4 5 6 7 8
/** * Retrieves and removes the head of this queue, waiting if necessary * until an element becomes available. * * @return the head of this queue * @throws InterruptedException if interrupted while waiting */ E take()throws InterruptedException;
/** * Acquires a permit from this semaphore, blocking until one is * available, or the thread is {@linkplain Thread#interrupt interrupted}. * * <p>Acquires a permit, if one is available and returns immediately, * reducing the number of available permits by one. * * <p>If no permit is available then the current thread becomes * disabled for thread scheduling purposes and lies dormant until * one of two things happens: * <ul> * <li>Some other thread invokes the {@link #release} method for this * semaphore and the current thread is next to be assigned a permit; or * <li>Some other thread {@linkplain Thread#interrupt interrupts} * the current thread. * </ul> * * <p>If the current thread: * <ul> * <li>has its interrupted status set on entry to this method; or * <li>is {@linkplain Thread#interrupt interrupted} while waiting * for a permit, * </ul> * then {@link InterruptedException} is thrown and the current thread's * interrupted status is cleared. * * @throws InterruptedException if the current thread is interrupted */ publicvoidacquire()throws InterruptedException { sync.acquireSharedInterruptibly(1); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/** * Releases a permit, returning it to the semaphore. * * <p>Releases a permit, increasing the number of available permits by * one. If any threads are trying to acquire a permit, then one is * selected and given the permit that was just released. That thread * is (re) enabled for thread scheduling purposes. * * <p>There is no requirement that a thread that releases a permit must * have acquired that permit by calling {@link #acquire}. * Correct usage of a semaphore is established by programming convention * in the application. */ publicvoidrelease(){ sync.releaseShared (1); }