原创

java面试题-当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象?

在Java多线程编程中,使用synchronized关键字是一种常见的同步机制,用于确保对共享资源的互斥访问。当一个线程进入一个对象的synchronized方法后,可能影响其他线程对同一对象的其他方法的访问。本教程将深入讨论这一问题,分为两种情况:进入非同步方法和进入同步方法。

1. 进入非同步方法

当一个线程进入一个对象的synchronized方法后,其它线程是否可进入此对象的非同步方法?答案是肯定的。

1.1 示例代码

public class SynchronizedExample {
    // 同步方法
    public synchronized void synchronizedMethod() {
        System.out.println(Thread.currentThread().getName() + "进入同步方法");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    // 非同步方法
    public void nonSynchronizedMethod() {
        System.out.println(Thread.currentThread().getName() + "进入非同步方法");
    }

    public static void main(String[] args) {
        SynchronizedExample example = new SynchronizedExample();

        // 线程1进入同步方法
        new Thread(() -> example.synchronizedMethod(), "线程1").start();

        // 休眠一段时间,确保线程1先进入同步方法
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 线程2进入非同步方法
        new Thread(() -> example.nonSynchronizedMethod(), "线程2").start();
    }
}

在上述代码中,线程1首先进入对象的同步方法synchronizedMethod,然后线程2进入对象的非同步方法nonSynchronizedMethod。这表明一个线程进入同步方法并不影响其他线程进入对象的非同步方法。

2. 进入同步方法

当一个线程进入一个对象的synchronized方法后,其他线程是否可进入此对象的同步方法?答案是否定的。

2.1 示例代码

public class SynchronizedExample {
    // 同步方法1
    public synchronized void synchronizedMethod1() {
        System.out.println(Thread.currentThread().getName() + "进入同步方法1");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    // 同步方法2
    public synchronized void synchronizedMethod2() {
        System.out.println(Thread.currentThread().getName() + "进入同步方法2");
    }

    public static void main(String[] args) {
        SynchronizedExample example = new SynchronizedExample();

        // 线程1进入同步方法1
        new Thread(() -> example.synchronizedMethod1(), "线程1").start();

        // 休眠一段时间,确保线程1先进入同步方法1
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 线程2尝试进入同步方法2
        new Thread(() -> example.synchronizedMethod2(), "线程2").start();
    }
}

在上述代码中,线程1首先进入对象的同步方法synchronizedMethod1,然后线程2尝试进入对象的同步方法synchronizedMethod2。由于线程1占有了对象的锁,线程2无法进入同步方法2,而是等待锁的释放。

3. 总结

在Java中,一个线程进入一个对象的synchronized方法后,不影响其他线程进入对象的非同步方法,但会阻塞其他线程进入对象的同步方法,直到锁被释放。这一特性是多线程编程中需要谨慎考虑的问题,以确保程序的正确性和性能。

正文到此结束
本文目录