Java多线程 6:synchronized 锁定类方法、volatile关键字及其他

同步静态方法快速到底

synchronized 还可以应用在静态方法上,如果这么写,则代表的是对当前 .java 文件对应的 Class 类加锁

Demo(注意一下 printC() 并不是一个静态方法

class ThreadDomain
{
    public synchronized static void printA()
    {
        try
        {
            System.out.println("线程名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "进入printA()方法");
            Thread.sleep(3000);
            System.out.println("线程名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "离开printA()方法");
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
    
    public synchronized static void printB()
    {
        System.out.println("线程名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "进入printB()方法");
        System.out.println("线程名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "离开printB()方法");

    }
    
    public synchronized void printC()
    {
        System.out.println("线程名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "进入printC()方法");
        System.out.println("线程名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "离开printC()方法");
    }
    
   
}

class MyThread_0 extends Thread
{
    public void run()
    {
        ThreadDomain.printA();
    }
}

class MyThread_1 extends Thread
{
    public void run()
    {
        ThreadDomain.printB();
    }
}


class MyThread_2 extends Thread
{
    private ThreadDomain td;
    
    public MyThread_2(ThreadDomain td)
    {
        this.td = td;
    }
    
    public void run()
    {
        td.printC();
    }
}
public class ThreadTest
{
     public static void main(String[] args)
        {
            ThreadDomain td = new ThreadDomain();
            MyThread_0 mt0 = new MyThread_0();
            MyThread_1 mt1 = new MyThread_1();
            MyThread_2 mt2 = new MyThread_2(td);
            
            mt0.start();
            mt1.start();
            mt2.start();
        }
}

运行结果

线程名称为:Thread-0 在1524535750225进入 printA()方法
线程名称为:Thread-2 在1524535750225进入 printC()方法
线程名称为:Thread-2 在1524535750225离开 printC()方法
                              // 注意:在这里有 3 秒停顿
线程名称为:Thread-0 在1524535753225离开 printA()方法
线程名称为:Thread-1 在1524535753225进入 printB()方法
线程名称为:Thread-1 在1524535753225离开 printB()方法

从运行结果来,对 printC() 方法的调用和对 printA() 方法、printB() 方法的调用时是异步的,这说明了静态同步方法和非静态同步方法持有的是不同的锁,前者是类锁,后者是对象锁

所谓类锁,举个再具体的例子。假如一个类中有一个静态同步方法 A,new 出了两个类的实例 B 和实例 C,线程 D 持有实例 B,线程 E 持有实例 C,只要线程 D 调用了 A 方法,那么线程 E 调用 A 方法必须等待线程 D 执行完 A 方法,尽管两个线程持有的是不同的对象。

猜你喜欢

转载自www.cnblogs.com/tkzL/p/8926768.html