Java中的LockSupport是一个用于线程同步的工具类,它可以用来阻塞和唤醒线程。LockSupport通过许可证的方式来控制线程的执行。每个线程都有一个许可证(permit),如果许可证可用,线程就可以继续执行,如果许可证不可用,线程就会被阻塞挂起。
具体来说,当调用LockSupport.park()方法时,如果当前线程已经拥有许可证,那么该方法会立即返回。否则,该线程就会被阻塞挂起,等待许可证的释放。而LockSupport.unpark(Thread t)方法可以用来释放线程的许可证,从而唤醒该线程继续执行。
LockSupport的实现基于操作系统的底层原语,使用了类似于信号量(semaphore)的机制,因此它比一些其他的线程同步工具(如synchronized)具有更低的开销和更高的可用性。
总的来说,LockSupport是一种灵活、高效的线程同步工具,它可以很好地支持各种线程同步场景,但需要注意使用时要遵循一些规范和最佳实践,避免出现线程死锁或其他问题。
在Java中,信号量(Semaphore)是一种用于多线程同步的机制。它可以限制同时访问某个资源的线程数量,从而保证多线程之间的协作和同步。
Semaphore内部维护一个计数器,用于记录可用的许可证数量。当一个线程需要访问某个受信号量保护的资源时,它必须先获取一个许可证,即通过调用acquire()方法来请求许可证。如果此时可用的许可证数量大于0,那么线程可以立即获取许可证并继续执行;否则,线程就会被阻塞挂起,等待其他线程释放许可证。
当一个线程访问完受信号量保护的资源后,它必须通过release()方法释放许可证,使得其他线程可以获取许可证并继续执行。当一个许可证被释放后,Semaphore内部的计数器会相应地增加,表示可用的许可证数量增加了。
Semaphore还提供了一些其他的操作,比如tryAcquire()方法可以尝试获取许可证而不被阻塞,release(int permits)方法可以一次性释放多个许可证等等。
总的来说,Semaphore是一种非常有用的多线程同步机制,可以用来限制并发访问某些资源的线程数量,从而保证线程安全和程序的正确性。但需要注意,使用Semaphore时要遵循一些规范和最佳实践,避免出现死锁或其他问题。
import java.util.concurrent.Semaphore;
public class ThreadLimitExample {
private static Semaphore semaphore = new Semaphore(2);
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 5; i++) {
new Thread(() -> {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " acquired semaphore");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
System.out.println(Thread.currentThread().getName() + " released semaphore");
}
}).start();
}
}
}
这个示例中,我们创建了一个Semaphore对象,并设置初始的许可证数量为2。然后创建了5个线程,每个线程执行的代码是先请求许可证(通过semaphore.acquire()方法),如果可用的许可证数量大于0,那么线程就可以获取许可证并继续执行;否则,线程就会被阻塞挂起。当线程执行完毕后,需要通过semaphore.release()方法释放许可证,使得其他线程可以获取许可证并继续执行。
由于初始的许可证数量为2,因此最多只有两个线程可以同时执行。如果有多于两个线程请求许可证,那么剩下的线程就会被阻塞挂起,直到有线程释放了许可证。
import java.util.concurrent.Semaphore;
public class TaskSequenceExample {
private static Semaphore semaphoreA = new Semaphore(1);
private static Semaphore semaphoreB = new Semaphore(0);
private static Semaphore semaphoreC = new Semaphore(0);
public static void main(String[] args) {
new Thread(() -> {
try {
semaphoreA.acquire();
System.out.println("Thread 1 running");
Thread.sleep(1000);
semaphoreB.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
semaphoreB.acquire();
System.out.println("Thread 2 running");
Thread.sleep(1000);
semaphoreC.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
semaphoreC.acquire();
System.out.println("Thread 3 running");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
semaphoreA.release();
}
}
这个示例中,我们创建了三个Semaphore对象,分别表示三个任务的执行顺序。初始时,semaphoreA的许可证数量为1,semaphoreB和semaphoreC的许可证数量为0。这样就保证了第一个任务可以先执行,而其他两个任务需要等待第一个任务执行完毕后才能继续执行。
在主线程中,我们启动了三个线程,分别对应三个任务。每个线程执行的代码都是先通过