CodeGym /Java 课程 /模块 3 /同步器:在 Java 中同步对资源的访问

同步器:在 Java 中同步对资源的访问

模块 3
第 19 级 , 课程 4
可用

信号

当使用文件系统时需要限制线程数时,通常会使用信号量。通过计数器控制对文件或其他共享资源的访问。如果其值大于零,则允许访问,但同时计数器会减少。

在计数器归零的那一刻,当前线程将被阻塞,直到资源被另一个线程释放。必须通过构造函数设置权限参数的数量。

您需要单独选择此参数,具体取决于您的计算机或笔记本电脑的功率。

public class Main {

   public static void main(String[] args) {
       Semaphore sem = new Semaphore(1);
       CommonResource res = new CommonResource();
       new Thread(new MyThread(res, sem, "MyThread_1")).start();
       new Thread(new MyThread(res, sem, "MyThread_2")).start();
       new Thread(new MyThread(res, sem, "MyThread_3")).start();
   }
}

class CommonResource {
   int value = 0;
}

class MyThread implements Runnable {
   CommonResource commonResource;
   Semaphore semaphore;
   String name;
   MyThread(CommonResource commonResource, Semaphore sem, String name) {
       this.commonResource = commonResource;
       this.semaphore = sem;
       this.name = name;
   }

   public void run() {

       try {
           System.out.println(name + "waiting permission");
           semaphore.acquire();
           commonResource.value = 1;
           for (int i = 1; i < 7; i++) {
               System.out.println(this.name + ": " + commonResource.value);
               commonResource.value++;
               Thread.sleep(150);
           }
       } catch (InterruptedException e) {
           System.out.println(e.getMessage() + " " + name);
           Thread.currentThread().interrupt();
       }
       System.out.println(name + "releases permission");
       semaphore.release();
   }
}

CountDownLatch 等

CountDownLatch - 允许多个线程等待,直到对其他线程执行的一定数量的操作完成。一个例子是应用程序的安装:直到您接受使用条款,它才会开始,直到您选择一个文件夹来安装新程序,等等。为此有一个特殊的countDown()方法- 此方法将倒计时计数器减一。

一旦计数归零,await 中的所有等待线程将继续其工作,并且所有后续的 await 调用将不等待而通过。递减计数器是一次性计数器,不能重置。

CyclicBarrier - 用于在某一点同步给定数量的线程。当 N 个线程调用 await(...) 方法并阻塞时达到屏障。之后,计数器被重置为原来的值,等待的线程将被释放。此外,如果需要,可以在取消阻塞线程和重置计数器之前运行自定义代码。为此,通过构造函数传递一个实现了Runnable接口的对象。

Exchanger<V> Exchanger类用于线程之间的数据交换。它是类型化的,类型是线程需要交换的数据类型。

使用此类唯一的exchange()方法交换数据:

V exchange(V x) throws InterruptedException
V exchange(V x, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException

x 参数表示要交换的数据缓冲区。该方法的第二种形式还定义了超时参数timeout 和unit,即用于超时参数的时间单位类型。

Phaser类允许您同步表示整体操作执行中的单个阶段或阶段的线程。Phaser定义了一个同步对象,它等待某个阶段完成。Phaser然后进入下一阶段或阶段并等待它再次完成。

使用Phaser类时,通常首先创建其对象。接下来,我们需要注册所有参与者。要为每个参与者注册,调用register()方法,或者您可以通过将所需数量的参与者传递给Phaser构造函数来不使用此方法。

然后每个参与者执行一组特定的动作,这些动作构成了这个阶段。Phaser同步器等待所有参与者完成阶段的执行。要通知同步器该阶段已结束,参与者必须调用arrive()arriveAndAwaitAdvance()方法。然后同步器进入下一阶段。

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION