Java multithreading 6: synchronized lock class method, volatile keyword and others

Synchronized static methodfast to the end

Synchronized can also be applied to static methods. If written like this, it means to lock the Class class corresponding to the current .java file .

Demo ( note that printC() is not a static method )

class ThreadDomain
{
    public synchronized static void printA()
    {
        try
        {
            System.out.println( "Thread name is: " + Thread.currentThread().getName() + "In" + System.currentTimeMillis() + "Enter printA() method" );
            Thread.sleep(3000);
            System.out.println( "Thread name is: " + Thread.currentThread().getName() + "In" + System.currentTimeMillis() + "Leave printA() method" );
        }
        catch (InterruptedException e)
        {
            e.printStackTrace ();
        }
    }
    
    public synchronized static void printB()
    {
        System.out.println( "Thread name is: " + Thread.currentThread().getName() + "In" + System.currentTimeMillis() + "Enter printB() method" );
        System.out.println( "Thread name is: " + Thread.currentThread().getName() + "In" + System.currentTimeMillis() + "Leave printB() method" );

    }
    
    public synchronized void printC()
    {
        System.out.println( "Thread name is: " + Thread.currentThread().getName() + "In" + System.currentTimeMillis() + "Enter printC() method" );
        System.out.println( "Thread name is: " + Thread.currentThread().getName() + "In" + System.currentTimeMillis() + "Leave printC() method" );
    }
    
   
}

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 方法,尽管两个线程持有的是不同的对象。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324878504&siteId=291194637