MST

星途 面试题库

面试题:Java多线程之线程同步问题

在Java多线程编程中,假设有多个线程同时访问和修改一个共享资源,可能会出现数据不一致的问题。请阐述synchronized关键字如何解决这种线程同步问题,并举例说明如何在代码中使用它来确保共享资源的安全访问。
45.1万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

1. synchronized关键字解决线程同步问题的原理

  • synchronized关键字通过互斥锁机制来解决线程同步问题。当一个线程进入被synchronized修饰的代码块或方法时,它会获取对应的锁。其他线程在尝试进入相同的被synchronized修饰的代码块或方法时,会发现锁已被占用,从而进入等待状态,直到持有锁的线程释放锁。这样就保证了同一时间只有一个线程能够访问共享资源,避免了数据不一致的问题。

2. 代码示例

示例一:同步方法

public class SynchronizedExample {
    private static int sharedResource = 0;

    // 同步方法
    public synchronized static void increment() {
        sharedResource++;
    }

    public static void main(String[] args) {
        Thread[] threads = new Thread[10];
        for (int i = 0; i < 10; i++) {
            threads[i] = new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    increment();
                }
            });
            threads[i].start();
        }

        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println("Final value of sharedResource: " + sharedResource);
    }
}

在上述代码中,increment方法被synchronized修饰,这意味着每次只有一个线程能够执行该方法,从而确保了对sharedResource的安全访问。

示例二:同步代码块

public class SynchronizedBlockExample {
    private static int sharedResource = 0;
    private static final Object lock = new Object();

    public static void increment() {
        synchronized (lock) {
            sharedResource++;
        }
    }

    public static void main(String[] args) {
        Thread[] threads = new Thread[10];
        for (int i = 0; i < 10; i++) {
            threads[i] = new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    increment();
                }
            });
            threads[i].start();
        }

        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println("Final value of sharedResource: " + sharedResource);
    }
}

在此示例中,使用synchronized块并指定了一个锁对象lock。所有线程在执行increment方法中的synchronized块时,都需要获取lock对象的锁,以此实现对sharedResource的同步访问。