Java面试题之多线程 举例说明同步和异步。
在Java中,多线程编程是一个重要的主题,理解同步和异步的概念对于编写高效的并发程序至关重要。下面我将通过示例来说明同步和异步的区别。
同步是指在多线程环境中,多个线程在访问共享资源时,必须按照一定的顺序进行,确保在同一时刻只有一个线程可以访问该资源。Java中可以使用synchronized
关键字来实现同步。
class Counter {
private int count = 0;
// 使用synchronized关键字来保证线程安全
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
public class SynchronizedExample {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
// 创建多个线程来增加计数器
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Final count: " + counter.getCount()); // 输出应为2000
}
}
在这个例子中,increment
方法是同步的,确保在同一时刻只有一个线程可以执行该方法,从而避免了数据竞争和不一致的问题。
异步是指多个线程可以并行执行,而不需要等待其他线程完成。Java中可以使用CompletableFuture
或其他异步编程模型来实现异步操作。
import java.util.concurrent.CompletableFuture;
public class AsynchronousExample {
public static void main(String[] args) {
// 创建一个异步任务
CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
try {
Thread.sleep(1000); // 模拟耗时操作
System.out.println("Task 1 completed");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> {
try {
Thread.sleep(500); // 模拟耗时操作
System.out.println("Task 2 completed");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 等待所有异步任务完成
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(future1, future2);
combinedFuture.join(); // 阻塞直到所有任务完成
System.out.println("All tasks completed");
}
}
在这个例子中,runAsync
方法创建了两个异步任务,它们可以并行执行。主线程不会等待第一个任务完成后再开始第二个任务,而是同时启动两个任务。最后,使用allOf
方法来等待所有异步任务完成。
synchronized
关键字实现。CompletableFuture
等工具实现。理解这两者的区别可以帮助你在多线程编程中做出更好的设计决策。