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

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

日前在网上见到一道Java笔试试题,如题所述。给出的答案如下:

答:不能,一个对象的一个synchronized方法只能由一个线程访问。

 

本人认为有些所答非所问。故写了两个demo进行测试。发现答案要分三种情况讨论。

 

情况一:

当一个线程进入一个对象的一个synchronized方法后,其它线程访问该对象的非同步方法。


public class TestSync
{
    public synchronized void run1()
    {
        for (int i = 0; i < 1000; i++)
        {
            System.out.println("execute run1");
            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }

    }

    public void run2()
    {
        for (int i = 0; i < 1000; i++)
        {
            System.out.println("execute run2");
            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
}

public class TestThread
{
    public static void main(String[] args)
    {
        final TestSync testSync = new TestSync();

        Thread thread1 = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                testSync.run1();
            }
        });

        Thread thread2 = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                testSync.run2();
            }
        });

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

 

运行结果:

一个线程在访问一个对象的同步方法时,另一个线程可以同时访问这个对象的非同步方法。

 

 

 

情况二:

当一个线程进入一个对象的一个synchronized方法后,其它线程也访问该同步方法。

 

运行结果:

一个线程在访问一个对象的同步方法时,另一个线程不能同时访问这个同步方法。(代码略)

 


情况三:

当一个线程进入一个对象的一个synchronized方法后,其它线程同时访问该对象的其他同步方法。


public class TestSync
{
    public synchronized void run1()
    {
        for (int i = 0; i < 1000; i++)
        {
            System.out.println("execute run1");
            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }

    }

    public synchronized void run2()
    {
        for (int i = 0; i < 1000; i++)
        {
            System.out.println("execute run2");
            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
}


public class TestThread
{
    public static void main(String[] args)
    {
        final TestSync testSync = new TestSync();

        Thread thread1 = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                testSync.run1();
            }
        });

        Thread thread2 = new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                testSync.run2();
            }
        });

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


运行结果:

前提条件:多个线程所持有的对象锁共享且唯一,如果每个线程所持有的对象锁不一样,那么该对象是锁不住的!

一个线程在访问一个对象的同步方法时,另一个线程不能同时访问这个对象的其他同步方法。


你可能感兴趣的:(JavaSE)