Java中的synchronized锁
在Java中,synchronized是一种关键字,用于实现线程同步。它可以用于方法或代码块,用于保证同一时间只有一个线程可以执行被synchronized修饰的代码。synchronized的锁机制有两种使用方式:1. 同步方法:可以在方法声明中使用synchronized关键字。当一个线程调用同步方法时,会自动获取该方法所属对象的锁,其他线程将被阻塞,直到该线程释放锁为止。2. 同步代码块:使
目录
1.如果synchronized锁加在实例方法上,则默认使用的是this锁
2.如果synchronized锁加载静态方法上,则默认使用的是 类名.class 锁(Java反射技术中说到一个class文件只会在jvm中存在一份)
3.死锁问题:在使用synchronized锁嵌套的时候,要避免死锁问题:
简介
在Java中,synchronized是一种关键字,用于实现线程同步。它可以用于方法或代码块,用于保证同一时间只有一个线程可以执行被synchronized修饰的代码。
synchronized的锁机制有两种使用方式:
1. 同步方法:可以在方法声明中使用synchronized关键字。当一个线程调用同步方法时,会自动获取该方法所属对象的锁,其他线程将被阻塞,直到该线程释放锁为止。
示例:
public synchronized void synchronizedMethod(){ // 同步代码块 } ```2. 同步代码块:使用synchronized关键字可以修饰一段代码块。当一个线程进入synchronized代码块时,它会尝试获取锁,如果锁已经被其他线程获取,那么该线程将被阻塞,直到锁被释放。
示例:
private Object lock = new Object(); public void synchronizedBlock(){ synchronized(lock){ // 同步代码块 } } ```需要注意的是,synchronized锁是基于对象的,每个对象都有一个关联的锁。当多个线程同时访问某个对象的同步方法或同步代码块时,它们会竞争该对象的锁。
另外,要注意避免过多地使用synchronized,因为过多的同步操作可能会导致性能下降。在某些情况下,可以考虑使用更灵活的并发工具,如Lock和Condition接口。
总之,synchronized是Java中用于实现线程同步的关键字,通过对方法或代码块进行同步,可以确保同一时间只有一个线程执行同步代码,从而保证线程安全。
注意:
1.如果synchronized锁加在实例方法上,则默认使用的是this锁
2.如果synchronized锁加载静态方法上,则默认使用的是 类名.class 锁(Java反射技术中说到一个class文件只会在jvm中存在一份)
3.死锁问题:在使用synchronized锁嵌套的时候,要避免死锁问题:
解决方案:
解决死锁问题的方法可以是以下几种:
1. 优化资源请求顺序:通过约定和统一的资源请求顺序,可以避免循环等待的情况发生。
2. 使用超时机制:在请求资源时,设置一个超时时间,在等待超过一定时间后放弃当前的资源请求,释放已持有的资源,然后重新尝试获取资源。
3. 使用资源分级:将资源进行划分,按照资源层级进行请求,确保每个线程只会请求当前层级的资源,防止多层级的资源竞争导致死锁。
4. 引入死锁检测算法:通过算法检测系统中是否存在死锁,并采取相应的措施解除死锁,例如资源剥夺、撤销进程等。
5. 使用Lock机制:使用Lock和Condition接口提供的功能来代替synchronized关键字,给予更灵活的控制,以避免发生死锁。
6. 尽量减少同步资源的使用:在设计时避免过多地使用同步资源,使用无锁算法或者减少共享资源的需求,可以降低发生死锁的概率。
7. 编写良好的代码和设计:遵循良好的编程原则和设计模式,减少不必要的资源竞争,尽量简化复杂的依赖关系,从根本上减少死锁的发生。
需要注意的是,死锁是一个复杂的问题,没有一种通用的解决方案适用于所有情况。因此,在编写多线程程序时,应该综合考虑业务逻辑和代码结构,并使用适当的方法来避免和处理死锁情况。
死锁案例:
package lzx6;
public class DeadlockExample {
private static final Object resource1 = new Object();
private static final Object resource2 = new Object();
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
synchronized (resource1) {
System.out.println("Thread 1: Holding resource 1...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 1: Waiting for resource 2...");
synchronized (resource2) {
System.out.println("Thread 1: Holding resource 1 and 2...");
}
}
});
Thread thread2 = new Thread(() -> {
synchronized (resource2) {
System.out.println("Thread 2: Holding resource 2...");
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Thread 2: Waiting for resource 1...");
synchronized (resource1) {
System.out.println("Thread 2: Holding resource 2 and 1...");
}
}
});
thread1.start();
thread2.start();
}
}
运行结果:

两个线程都在等待对方释放资源,所以两个线程都发生了死锁卡住了。
更多推荐


所有评论(0)