21xrx.com
2024-12-22 21:21:39 Sunday
登录
文章检索 我的文章 写文章
Java 多线程编程:使用代码解决实例问题
2023-07-07 12:34:28 深夜i     --     --
Java 多线程 编程 代码 实例问题

Java 多线程编程是 Java 语言中一个非常重要的概念,可以使程序员可以更好地利用计算机多核的优势,提高程序的性能和效率。本文将使用一个实例来演示如何使用 Java 多线程编程来解决问题。

假设有一个商场,里面有 10 个店铺,每个店铺都有自己的员工。在早上 9 点,商场开门营业,并且每家店铺都需要进行开门营业准备工作,例如清理门面、摆放商品等。当所有店铺的准备工作都完成后,商场才会正式营业。

在单线程情况下,我们可以使用一个循环遍历每个店铺,然后依次对每个店铺进行开门营业准备工作,等到全部店铺准备完毕后再开门营业。下面是代码实现:


public class Main {

  public static void main(String[] args) {

    List<Shop> shops = new ArrayList<>();

    // 创建 10 个店铺

    for (int i = 0; i < 10; i++) {

      shops.add(new Shop("店铺" + i));

    }

    // 遍历每个店铺,进行开门营业准备工作

    for (Shop shop : shops) {

      shop.prepare();

    }

    // 开始正式营业

    System.out.println("商场正式营业!");

  }

}

class Shop {

  private String name; // 店铺名

  public Shop(String name)

    this.name = name;

  

  // 开门营业准备工作

  public void prepare() {

    System.out.println(name + " 开始准备开门营业!");

    try {

      Thread.sleep(1000); // 模拟准备工作需要耗费的时间

    } catch (InterruptedException e) {

      e.printStackTrace();

    }

    System.out.println(name + " 完成开门营业准备工作!");

  }

}

但是,上述代码有一个很明显的缺点:顺序进行开门营业准备工作的过程是串行的,也就是说每个店铺必须等待前一个店铺的准备工作完成后才能开始自己的准备工作,这显然浪费了时间。现在,我们来用多线程编程的思路来解决这个问题。

我们可以创建 10 个线程,每个线程对应一个店铺,同时对每个店铺进行开门营业准备工作。这样,当一个店铺还在进行准备工作时,其他店铺也可以开始自己的准备工作,这样可以大大提高准备工作的效率。下面是代码实现:


public class Main {

  public static void main(String[] args) throws InterruptedException {

    CountDownLatch latch = new CountDownLatch(10); // 创建一个倒计时计数器,设置计数器值为 10

    List<Thread> threads = new ArrayList<>();

    // 创建 10 个线程,每个线程分别对一个店铺进行开门营业准备工作

    for (int i = 0; i < 10; i++) {

      threads.add(new Thread(new ShopTask(latch, "店铺" + i)));

    }

    // 启动所有线程

    for (Thread thread : threads) {

      thread.start();

    }

    // 等待所有线程执行完毕

    latch.await();

    // 开始正式营业

    System.out.println("商场正式营业!");

  }

}

class ShopTask implements Runnable {

  private CountDownLatch latch; // 倒计时计数器

  private String name; // 店铺名

  public ShopTask(CountDownLatch latch, String name)

    this.latch = latch;

    this.name = name;

  

  @Override

  public void run() {

    System.out.println(name + " 开始准备开门营业!");

    try {

      Thread.sleep(1000); // 模拟准备工作需要耗费的时间

    } catch (InterruptedException e) {

      e.printStackTrace();

    }

    System.out.println(name + " 完成开门营业准备工作!");

    latch.countDown(); // 让倒计时计数器的值减 1

  }

}

注意,我们使用了一个 `CountDownLatch` 类来实现这个多线程问题的解决方案。`CountDownLatch` 是一个非常实用的类,可以让一个或多个线程等待一组事件的发生,再继续执行。在我们的例子中,我们使用 `CountDownLatch` 的计数器功能,每个线程执行完准备工作后都会对计数器进行减一操作,当所有线程都执行完准备工作后,这个计数器的计数值将变成 0,主线程等待所有线程执行完毕时会通过 `CountDownLatch.await()` 方法阻塞自己,直到计数器的值为 0,再继续向下执行。

通过上述多线程编程的方式,我们成功地解决了原先的单线程解决方案存在的问题,实现了更加高效、并行的开门营业准备工作过程,提高了商场的营业效率,也提高了我们编程的技能和水平。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复