欢迎访问宙启技术站
智能推送

Java中如何使用多线程实现同步和异步执行任务?

发布时间:2023-06-06 13:30:06

Java在语言层面就提供了多线程支持,因此在Java中可以轻易地使用多线程来实现同步和异步执行任务。

1. 同步执行任务

在Java中,同步执行任务可以通过synchronized关键字代码块或方法来实现。synchronized确保在同一时间只有一个线程可以访问代码块或方法,从而确保线程安全,避免竞态条件和死锁。

下面是一个使用synchronized实现同步执行任务的示例:

public class SyncTask implements Runnable {
  private int count = 0;

  public void run() {
    synchronized (this) {
      for (int i = 0; i < 1000; i++) {
        count++;
      }
      System.out.println(Thread.currentThread().getName() + " finished, count is " + count);
    }
  }
}

public class Main {
  public static void main(String[] args) throws InterruptedException {
    SyncTask task = new SyncTask();
    Thread t1 = new Thread(task);
    Thread t2 = new Thread(task);
    t1.start();
    t2.start();
    t1.join();
    t2.join();
    System.out.println("Finished, final count is " + task.getCount());
  }
}

在上述示例中,SyncTask实现了Runnable接口的run方法,在run方法中使用synchronized关键字确保count共享变量的线程安全。在Main类中,创建了两个线程并分别启动,最后join等待线程执行结束,并获取SyncTask的count变量的最终值输出。

2. 异步执行任务

Java中异步执行任务可以通过创建线程池并提交异步任务来实现。这种方式会把任务提交到线程池中,由线程池自动管理线程的创建和销毁。这种方式可以避免频繁创建销毁线程的开销,提高程序性能。

下面是一个使用线程池实现异步执行任务的示例:

public class AsyncTask implements Callable<Long> {
  public Long call() throws Exception {
    long result = 0;
    for (int i = 0; i < 100000; i++) {
      result += i;
    }
    return result;
  }
}

public class Main {
  public static void main(String[] args) throws Exception {
    ExecutorService executorService = Executors.newFixedThreadPool(2);
    List<Future<Long>> futureList = new ArrayList<Future<Long>>();
    for (int i = 0; i < 5; i++) {
      Future<Long> future = executorService.submit(new AsyncTask());
      futureList.add(future);
    }
    executorService.shutdown();
    for (Future<Long> future : futureList) {
      System.out.println(future.get());
    }
  }
}

在上述示例中,AsyncTask实现了Callable接口的call方法,在call方法中实现了一个简单的累加任务。在Main类中,创建了一个固定大小为2的线程池,并提交了5个异步任务,将返回结果future添加到futureList中。最后通过future的get方法获取异步任务执行的结果并输出。

总结

Java中使用多线程实现同步和异步执行任务非常简单。同步执行任务可以使用synchronized关键字,而异步执行任务可以使用线程池。但是,在使用多线程时必须小心线程安全问题,避免资源竞争和死锁的发生。