目录

简介

注意:

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();
    }
}

运行结果:

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

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐