您好,登录后才能下订单哦!
在Java中,synchronized
关键字用于实现线程同步,确保多个线程在访问共享资源时能够正确地进行协调。synchronized
可以用于方法或代码块,它的核心原理是通过锁机制来实现线程的互斥访问。
对象锁:当synchronized
修饰实例方法时,锁的是当前对象实例。多个线程访问同一个对象的同步方法时,会互斥执行。
类锁:当synchronized
修饰静态方法时,锁的是当前类的Class对象。多个线程访问同一个类的静态同步方法时,会互斥执行。
在JVM中,每个对象都有一个与之关联的监视器锁(Monitor)。当一个线程进入synchronized
代码块时,它会尝试获取对象的监视器锁。如果锁没有被其他线程持有,当前线程将成功获取锁并继续执行。如果锁已经被其他线程持有,当前线程将进入阻塞状态,直到锁被释放。
JVM对synchronized
进行了多种优化,以提高并发性能:
偏向锁:如果一个线程多次获取同一个锁,JVM会将锁偏向该线程,减少锁的获取和释放开销。
轻量级锁:当多个线程交替执行同步代码块时,JVM会使用轻量级锁来避免线程阻塞。
自旋锁:当线程获取锁失败时,JVM会让线程自旋等待一段时间,而不是立即进入阻塞状态,以减少线程切换的开销。
public class SynchronizedExample {
private int count = 0;
public synchronized void increment() {
count++;
}
public static synchronized void staticIncrement() {
// 类锁
}
public void blockIncrement() {
synchronized (this) {
count++;
}
}
}
Callable
接口是Java并发编程中的一个重要接口,它与Runnable
接口类似,但Callable
可以返回一个结果,并且可以抛出异常。Callable
通常与ExecutorService
一起使用,用于执行异步任务。
返回值:Callable
的call()
方法可以返回一个结果,而Runnable
的run()
方法没有返回值。
异常处理:Callable
的call()
方法可以抛出异常,而Runnable
的run()
方法不能抛出受检异常。
Callable
接口,并重写call()
方法。ExecutorService
实例。Callable
任务给ExecutorService
执行。Future
对象获取任务执行结果。import java.util.concurrent.*;
public class CallableExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<Integer> task = () -> {
int sum = 0;
for (int i = 1; i <= 10; i++) {
sum += i;
}
return sum;
};
Future<Integer> future = executor.submit(task);
System.out.println("Sum: " + future.get());
executor.shutdown();
}
}
Future
接口表示异步计算的结果。它提供了以下方法:
get()
:获取计算结果,如果计算未完成,则阻塞当前线程直到计算完成。
isDone()
:判断任务是否完成。
cancel()
:尝试取消任务的执行。
synchronized
关键字通过锁机制实现了线程的互斥访问,确保了多线程环境下共享资源的安全性。JVM对synchronized
进行了多种优化,以提高并发性能。
Callable
接口提供了比Runnable
更强大的功能,允许任务返回结果并抛出异常。通过ExecutorService
和Future
,我们可以方便地执行异步任务并获取结果。
在实际开发中,合理使用synchronized
和Callable
可以有效地提高程序的并发性能和可靠性。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。