写个小类,希望同时只有一个任务在执行,其它任务来之后,直接返回false。
首先尝试了synchronized,代码如下:
package thread;
import java.util.Random;
public class CmdRunnerSynchronized {
public static boolean IS_RUNNING = false;
private static final Object lock = new Object();
public boolean start() {
// 如果有任务在执行,直接返回 if (IS_RUNNING) { System.out.println("--is running---" + Thread.currentThread().getName()); return false; }
// sleep一会 try { Thread.sleep(new Random().nextInt(2000)); } catch (InterruptedException e) { e.printStackTrace(); }
synchronized (lock) { IS_RUNNING = true; System.out.println("--run start---" + Thread.currentThread().getName());
// sleep一会 try { Thread.sleep(new Random().nextInt(2000)); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("--run end---" + Thread.currentThread().getName()); IS_RUNNING = false; }
return true; }
public static void main(String[] args) {
// 开10个线程 for (int i = 0; i < 10; i++) { new Thread("Thread" + i) { public void run() { try { Thread.sleep(new Random().nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } CmdRunnerSynchronized run = new CmdRunnerSynchronized(); run.start(); } }.start(); } } }
运行结果如下: ------------------------------ --run start---Thread0 --is running---Thread6 --run end---Thread0 --run start---Thread9 --is running---Thread4 --is running---Thread8 --is running---Thread3 --run end---Thread9 --run start---Thread2 --run end---Thread2 --run start---Thread7 --run end---Thread7 --run start---Thread1 --run end---Thread1 --run start---Thread5 --run end---Thread5 ------------------------------ 只有3,4,6,8直接返回了,其它都等待,直到被执行。 这是因为开始的IS_RUNNING判断,这些线程都通过了,然后在synchronized处等待。 这样不符合要求。
然后想到了传说中的ReentrantLock,它有个tryLock()方法, 取到锁的话,返回true,没取到的话,马上返回false,不等待的~~ 大概用法如下: ------------------ Lock lock = ...; if (lock.tryLock()) { try { // manipulate protected state } finally { lock.unlock(); } } else { // perform alternative actions } ------------------ 代码改改如下:
package thread;
import java.util.Random; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;
public class CmdRunner {
public static boolean IS_RUNNING = false;
private static Lock scoreLock = new ReentrantLock();
public boolean start() {
if (scoreLock.tryLock()) { try {
// sleep一会 try { Thread.sleep(new Random().nextInt(2000)); } catch (InterruptedException e) { e.printStackTrace(); }
IS_RUNNING = true; System.out.println("--run start---" + Thread.currentThread().getName());
// sleep一会 try { Thread.sleep(new Random().nextInt(2000)); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("--run end---" + Thread.currentThread().getName()); IS_RUNNING = false; return true; } finally { scoreLock.unlock(); } } else { System.out.println("--is running---" + Thread.currentThread().getName()); return false; }
}
public static void main(String[] args) {
// 开10个线程 for (int i = 0; i < 10; i++) { new Thread("Thread" + i) { public void run() { try { Thread.sleep(new Random().nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } CmdRunner run = new CmdRunner(); run.start(); } }.start(); } } }
运行结果如下: ------------------- --is running---Thread8 --is running---Thread4 --is running---Thread9 --is running---Thread2 --is running---Thread5 --is running---Thread0 --is running---Thread7 --is running---Thread6 --run start---Thread1 --is running---Thread3 --run end---Thread1 ---------------------- 都是一个线程执行,其它直接返回。
|