synchronized 关键字

synchronized 关键字在多线程环境中,保证线程安全是至关重要的。synchronized 是Java中用于同步的一个关键字,它提供了一种简单的方法来防止多个线程同时访

欢迎大家来到IT世界,在知识的湖畔探索吧!

在多线程环境中,保证线程安全是至关重要的。synchronized 是Java中用于同步的一个关键字,它提供了一种简单的方法来防止多个线程同时访问某个资源。

为什么需要 synchronized?

当多个线程同时访问某个对象或类的某些部分,并试图修改其状态时,可能会出现不可预测的行为。为了避免这种情况,我们需要一种机制来确保在任何时候只有一个线程能够访问这些部分。

如何使用 synchronized?

同步方法:您可以直接在方法声明上使用 synchronized 关键字。

public synchronized void synchronizedMethod() {
    // ... critical section ...
}

欢迎大家来到IT世界,在知识的湖畔探索吧!

这样,同一时刻只能有一个线程可以执行该方法。

同步代码块:如果您只希望同步方法中的某一部分代码,可以使用同步代码块。

欢迎大家来到IT世界,在知识的湖畔探索吧!public void someMethod() {
    // ... some non-critical code ...
    
    synchronized(this) {
        // ... critical section ...
    }
    
    // ... some other non-critical code ...
}

在这里,我们使用 this 作为同步对象,但您也可以使用其他对象。

示例:

考虑以下的示例代码:

class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }
}

在这个例子中,我们有一个简单的计数器。使用 synchronized 关键字确保在任何时候只有一个线程可以增加计数或获取当前计数。这保证了线程安全性。

注意事项:

synchronized 引入了一个性能开销,因为每次只允许一个线程访问同步的代码部分。所以,尽量只同步必要的代码部分。

使用 synchronized 可能会导致死锁,特别是当您有多个线程尝试获取多个锁时。以下是一个使用 synchronized 导致死锁的经典示例:

欢迎大家来到IT世界,在知识的湖畔探索吧!public class DeadlockDemo {
    private static final Object Lock1 = new Object();
    private static final Object Lock2 = new Object();

    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            synchronized (Lock1) {
                System.out.println("Thread 1: Holding Lock1...");
                try { Thread.sleep(100); } catch (InterruptedException e) {}
                System.out.println("Thread 1: Waiting for Lock2...");
                synchronized (Lock2) {
                    System.out.println("Thread 1: Acquired Lock2!");
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            synchronized (Lock2) {
                System.out.println("Thread 2: Holding Lock2...");
                try { Thread.sleep(100); } catch (InterruptedException e) {}
                System.out.println("Thread 2: Waiting for Lock1...");
                synchronized (Lock1) {
                    System.out.println("Thread 2: Acquired Lock1!");
                }
            }
        });

        thread1.start();
        thread2.start();
    }
}

在上述代码中,我们有两个锁:Lock1 和 Lock2。thread1 尝试首先获取 Lock1,然后获取 Lock2,而 thread2 则尝试首先获取 Lock2,然后获取 Lock1。由于两个线程之间的竞争,它们最终都被阻塞,因为它们都在等待对方释放另一个锁。

为了避免死锁,我们需要确保所有线程都按相同的顺序获取锁,或者使用更高级的并发工具和技术(例如 ReentrantLock)来更灵活地控制锁定。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/35618.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信