比特币网站怎么做能答题做试卷的网站

当前位置: 首页 > news >正文

比特币网站怎么做,能答题做试卷的网站,企业网站蓝色模板下载,怎样创建网站吉洋大鼓目录 1 互斥性 2 公平性 3 可重入性 4 获取和释放锁 5 尝试获取锁 6 可中断的锁定 7 条件变量 8 性能 9 使用场景 ReentrantLock 是 Java 提供的一种可重入的互斥锁#xff0c;位于 java.util.concurrent.locks 包中#xff0c;它实现了 Lock 接口。这个锁提供了与内…目录 1 互斥性 2 公平性 3 可重入性 4 获取和释放锁 5 尝试获取锁 6 可中断的锁定 7 条件变量 8 性能 9 使用场景 ReentrantLock 是 Java 提供的一种可重入的互斥锁位于 java.util.concurrent.locks 包中它实现了 Lock 接口。这个锁提供了与内置监视器锁通过 synchronized 关键字实现类似的互斥性和内存可见性但具有更强大的功能和灵活性。以下是 ReentrantLock 的一些基本概念 1 互斥性 ReentrantLock 可以确保同一时间只有一个线程可以执行由该锁保护的代码块从而避免了竞态条件。 2 公平性 非公平锁默认情况下ReentrantLock 是非公平的。这意味着线程获取锁的顺序并不是按照它们请求锁的顺序来确定的。非公平锁通常提供更高的吞吐量。公平锁当创建 ReentrantLock 实例时可以通过传入 true 参数来指定为公平锁。公平锁保证线程将按照它们请求锁的顺序获得锁。这可能会降低吞吐量但能减少饥饿现象。 示例代码默认是非公平锁如果需要公平锁则在构造函数中传入 true。 import java.util.concurrent.locks.ReentrantLock;// 默认非公平锁 ReentrantLock lock new ReentrantLock();// 公平锁 ReentrantLock fairLock new ReentrantLock(true); 3 可重入性 可重入意味着如果一个线程已经持有某个锁那么它可以再次获取这个锁而不会被阻塞。这是非常有用的特性因为它允许方法在调用其他可能也需要相同锁的方法时不会导致死锁。 示例代码 public void reentrantExample() {lock.lock();try {// 第一次获取锁System.out.println(First time locked, thread: Thread.currentThread().getName());// 在已经持有锁的情况下再次获取锁lock.lock();try {System.out.println(Second time locked, thread: Thread.currentThread().getName());} finally {lock.unlock(); // 释放第二次获取的锁}} finally {lock.unlock(); // 释放第一次获取的锁} } 输出结果 First time locked, thread: main Second time locked, thread: main 使用可重入锁的具体例子假设有一个类其中包含一个递归方法且这个方法需要是线程安全的。由于方法会多次调用自身因此需要一个可重入锁来确保同一个线程可以重复获取锁。 import java.util.concurrent.locks.ReentrantLock;public class FactorialCalculator {private final ReentrantLock lock new ReentrantLock();public int factorial(int number) {lock.lock(); // 获取锁try {if (number 1) {return 1;} else {return number * factorial(number - 1); // 递归调用}} finally {lock.unlock(); // 释放锁}} } 4 获取和释放锁 获取锁通过调用 lock() 方法释放锁则通过 unlock() 方法。通常建议在 finally 块中释放锁以确保即使发生异常也能正确释放锁。 public void doSomething() {lock.lock();try {// 执行同步代码} finally {lock.unlock();} } 5 尝试获取锁 tryLock() 方法尝试获取锁如果无法立即获得锁则返回 false不会阻塞线程。 if (lock.tryLock()) { // 尝试获取锁如果无法获取则立即返回falsetry {// 执行同步代码} finally {lock.unlock();} } else {// 锁未获得时的操作 } tryLock() 方法有两个版本 无参数的 tryLock()尝试获取锁如果锁可用则立即获取并返回 true否则立即返回 false。带超时的 tryLock(long timeout, TimeUnit unit)尝试获取锁如果在指定的时间内可以获取到锁则返回 true如果超过了指定时间仍无法获取到锁则返回 false。 具体使用示例 无参数的 tryLock() import java.util.concurrent.locks.ReentrantLock;public class TryLockExample {private final ReentrantLock lock new ReentrantLock();public void doWork() {if (lock.tryLock()) { // 尝试获取锁try {// 执行需要同步的操作System.out.println(Thread Thread.currentThread().getName() is doing work.);} finally {lock.unlock(); // 确保释放锁}} else {// 如果无法获取锁执行其他操作System.out.println(Thread Thread.currentThread().getName() could not get the lock and will do something else.);}}public static void main(String[] args) {TryLockExample example new TryLockExample();// 创建两个线程来调用 doWork 方法Thread t1 new Thread(() - example.doWork(), Thread-1);Thread t2 new Thread(() - example.doWork(), Thread-2);t1.start();t2.start();} } 在这个例子中如果 Thread-1 先获取到了锁那么 Thread-2 将无法获取锁并且会直接输出“无法获取锁”的信息。 带超时的 tryLock(long timeout, TimeUnit unit)  import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock;public class TryLockWithTimeoutExample {private final ReentrantLock lock new ReentrantLock();public void doWork() {boolean locked false;try {// 尝试在5秒内获取锁locked lock.tryLock(5, TimeUnit.SECONDS);if (locked) {// 执行需要同步的操作System.out.println(Thread Thread.currentThread().getName() is doing work.);} else {// 如果在5秒内无法获取锁执行其他操作System.out.println(Thread Thread.currentThread().getName() could not get the lock within 5 seconds and will do something else.);}} catch (InterruptedException e) {// 处理中断异常Thread.currentThread().interrupt();System.out.println(Thread Thread.currentThread().getName() was interrupted while waiting for the lock.);} finally {if (locked) {lock.unlock(); // 确保释放锁}}}public static void main(String[] args) {TryLockWithTimeoutExample example new TryLockWithTimeoutExample();// 创建两个线程来调用 doWork 方法Thread t1 new Thread(() - example.doWork(), Thread-1);Thread t2 new Thread(() - example.doWork(), Thread-2);t1.start();t2.start();} } 在这个例子中如果 Thread-1 持有锁超过5秒钟那么 Thread-2 将会在等待5秒后放弃尝试获取锁并执行相应的逻辑。 使用场景 避免死锁当多个线程试图以不同的顺序获取多个锁时可能会导致死锁。使用 tryLock() 可以帮助检测这种情况并采取适当的措施。提高响应性在某些情况下你可能不希望线程一直等待锁而是希望线程能够快速响应其他任务。这时可以使用 tryLock() 来检查锁是否可用如果不可用就立即执行其他工作。资源竞争控制在资源有限的情况下可以使用 tryLock() 来尝试获取资源如果获取不到则可以选择放弃或重试。 6 可中断的锁定 lockInterruptibly() 方法允许在等待获取锁的过程中响应中断。 try {lock.lockInterruptibly(); // 尝试获取锁可以响应中断try {// 执行同步代码} finally {lock.unlock();} } catch (InterruptedException e) {// 处理中断情况 } 示例代码 import java.util.concurrent.locks.ReentrantLock;public class CancellableTask {private final ReentrantLock lock new ReentrantLock();private boolean isCancelled false;public void runTask() {Thread thread new Thread(() - {try {// 尝试获取锁同时可以响应中断lock.lockInterruptibly();try {// 模拟任务执行while (!isCancelled) {System.out.println(Task is running…);// 假设任务需要一段时间完成Thread.sleep(1000);}} finally {lock.unlock();}} catch (InterruptedException e) {System.out.println(Task was interrupted, stopping execution.);// 通常在这里你会清理资源并退出// 重新设置中断状态以便调用者知道该线程已被中断Thread.currentThread().interrupt();}});thread.start();// 在某个时刻决定取消任务try {Thread.sleep(3000); // 等待几秒钟} catch (InterruptedException e) {e.printStackTrace();}isCancelled true;thread.interrupt(); // 中断线程}public static void main(String[] args) {CancellableTask task new CancellableTask();task.runTask();} } 当主线程决定取消任务时它会中断工作线程。工作线程会在 lockInterruptibly() 调用处立即响应中断并抛出 InterruptedException从而允许任务快速终止。  输出结果 Task is running… Task is running… Task is running… Task was interrupted, stopping execution. 除了使用 lockInterruptibly() 来实现中断锁还可以使用带超时的 tryLock(long timeout, TimeUnit unit)来达成这一目的。以下是例子 import java.util.concurrent.locks.ReentrantLock;public class ResourceService {private final ReentrantLock resourceLock new ReentrantLock();public void useResource() {Thread thread new Thread(() - {try {if (resourceLock.tryLock()) {try {// 使用资源System.out.println(Using resource…);Thread.sleep(10000); // 模拟长时间操作} finally {resourceLock.unlock();}} else {System.out.println(Could not acquire the resource, operation is cancelled.);}} catch (InterruptedException e) {System.out.println(Resource usage was interrupted, releasing the resource.);resourceLock.unlock(); // 如果已经获得锁则释放Thread.currentThread().interrupt(); // 保持中断状态}});thread.start();// 在某个时刻决定取消使用资源的操作try {Thread.sleep(5000); // 等待几秒钟} catch (InterruptedException e) {e.printStackTrace();}thread.interrupt(); // 中断线程}public static void main(String[] args) {ResourceService service new ResourceService();service.useResource();} } 是的tryLock(long time, TimeUnit unit) 方法也可以响应中断。当一个线程调用 tryLock(long time, TimeUnit unit) 时它会尝试在指定的时间内获取锁。如果在这段时间内没有获取到锁方法将返回 false。此外如果在此期间线程被中断该方法会立即抛出 InterruptedException 并且不会获取锁。  注意ReentrantLock 的 lock() 方法确实不会响应中断。当一个线程调用 lock() 试图获取锁时如果锁已经被其他线程持有那么该线程将一直阻塞直到它能够获取到锁为止。即使在此期间该线程被中断例如通过调用 Thread.interrupt()它也不会抛出 InterruptedException 或者以其他方式退出等待状态。只有在获取到锁之后中断状态才会被检查。 7 条件变量 ReentrantLock 提供了条件变量 Condition它可以替代传统的 Object.wait/notify 机制。这些对象类似于 Object 类中的 wait/notify 机制但是更加灵活。每个 Condition 实例都可以独立地挂起和唤醒线程这对于复杂的同步需求是非常有用的。 下面是一个具体的例子展示了如何使用条件变量来实现生产者-消费者模式 在这个模式中有一个共享缓冲区生产者向缓冲区添加元素消费者从缓冲区移除元素。当缓冲区满时生产者必须等待当缓冲区空时消费者必须等待。 import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; import java.util.LinkedList;public class ProducerConsumerExample {private final int BUFFER_SIZE 5; // 缓冲区大小private final LinkedListInteger buffer new LinkedList();private final ReentrantLock lock new ReentrantLock();private final Condition notFull lock.newCondition(); // 缓冲区不满的条件private final Condition notEmpty lock.newCondition(); // 缓冲区不空的条件public void put(int value) throws InterruptedException {lock.lock();try {// 如果缓冲区已满则等待while (buffer.size() BUFFER_SIZE) {notFull.await();}// 向缓冲区添加元素buffer.add(value);System.out.println(Produced: value);// 唤醒可能正在等待的消费者notEmpty.signal();} finally {lock.unlock();}}public int get() throws InterruptedException {lock.lock();try {// 如果缓冲区为空则等待while (buffer.isEmpty()) {notEmpty.await();}// 从缓冲区移除元素int value buffer.removeFirst();System.out.println(Consumed: value);// 唤醒可能正在等待的生产者notFull.signal();return value;} finally {lock.unlock();}}public static void main(String[] args) {final ProducerConsumerExample example new ProducerConsumerExample();Thread producerThread new Thread(() - {for (int i 0; i 20; i) {try {example.put(i);Thread.sleep(100); // 模拟生产时间} catch (InterruptedException e) {Thread.currentThread().interrupt();break;}}});Thread consumerThread new Thread(() - {for (int i 0; i 20; i) {try {example.get();Thread.sleep(200); // 模拟消费时间} catch (InterruptedException e) {Thread.currentThread().interrupt();break;}}});producerThread.start();consumerThread.start();try {producerThread.join();consumerThread.join();} catch (InterruptedException e) {e.printStackTrace();}} } 代码解释  ReentrantLock 和 Condition我们使用 ReentrantLock 来保护对共享资源即缓冲区的访问并且创建了两个条件变量 notFull 和 notEmpty。put() 方法生产者调用此方法向缓冲区添加数据。如果缓冲区已满则生产者将调用 notFull.await() 等待直到有空间可用。一旦添加了数据就通过 notEmpty.signal() 通知等待中的消费者。get() 方法消费者调用此方法从缓冲区获取数据。如果缓冲区为空则消费者将调用 notEmpty.await() 等待直到有数据可用。一旦取出了数据就通过 notFull.signal() 通知等待中的生产者。主线程启动生产者和消费者线程并等待它们完成。 8 性能 ReentrantLock 在某些情况下比 synchronized 更高效尤其是在高度竞争的情况下。这是因为 ReentrantLock 可以使用自旋而不是完全阻塞来等待锁这样可以减少上下文切换的成本。 9 使用场景 当你需要比 synchronized 更细粒度的控制时例如尝试获取锁、响应中断或使用多个条件变量。当你需要实现公平锁时。当你希望在性能上有所提升并且能够处理高级并发模式时。 示例代码 import java.util.concurrent.locks.ReentrantLock;public class ReentrantLockExample {private final ReentrantLock lock new ReentrantLock();public void doSomething() {// 获取锁lock.lock();try {// 执行需要同步的操作System.out.println(Thread Thread.currentThread().getName() is doing something.);} finally {// 确保锁最终会被释放lock.unlock();}}public static void main(String[] args) {ReentrantLockExample example new ReentrantLockExample();// 创建两个线程来调用 doSomething 方法Thread t1 new Thread(() - example.doSomething(), Thread-1);Thread t2 new Thread(() - example.doSomething(), Thread-2);t1.start();t2.start();} } 在这个例子中doSomething 方法使用 ReentrantLock 来确保每次只有一个线程可以执行其中的代码。注意在 finally 块中释放锁以防止因异常导致锁未被释放的情ss