见SynchronizedDemo.java的源码理解synchronized

/**
 * Synchronized理解:
 *    根据如下4个例子总结如下:
 *         Synchronized修饰方法和Synchronized(this)修饰代码块一样,当一个线程进入一个对象A的synchronized方法或Synchronized(this)方法块的同时,其它线程不能进入该对象的任何synchronized方法和Synchronized(this)方法块
 *         static Synchronized修饰方法和Synchronized(*.class)修饰代码块一样,当一个线程进入一个类的static synchronized方法或Synchronized(*.class)方法块的同时,其它线程不能进入该类的任何static synchronized方法和Synchronized(*.class)方法块
 **/
public class SynchronizedDemo{
    /**
     * 例1:
     * 同一个对象:
     * 当一个线程进入一个对象A的synchronized方法的同时,其它线程不能进入该对象的任何synchronized方法
     **/
    private void showSynchronizedResult1(){
        final Sync testSync1 = new Sync();

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

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

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

    /**
     * 例2:
     * 同一个对象:
     * 当一个线程进入一个对象A的synchronized方法的同时,其它线程可以进入该对象的普通方法
     **/
    private void showSynchronizedResult2(){
        final Sync testSync1 = new Sync();

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

        Thread thread3 = new Thread(new Runnable(){
            @Override
            public void run(){
                testSync1.run3();
            }
        });

        thread1.start();
        thread3.start();
    }

    /**
     * 例3:
     * 不同对象
     * 当一个线程进入一个对象A的synchronized方法的同时,其它线程可以进入其他对象的synchronized方法,互不影响
     **/
    private void showSynchronizedResult3(){
        final Sync testSync1 = new Sync();
        final Sync testSync2 = new Sync();

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

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

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

    /**
     * 例4:
     * 当一个线程进入一个static synchronized方法的同时,其它线程不可以进入任何的static synchronized方法
     **/
    private void showStaticSynchronizedResult4(){
        Thread thread1 = new Thread(new Runnable(){
            @Override
            public void run(){
                Sync.run4();
            }
        });

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

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

    public static void main(String args[]){
        // 例1:多线程下同一对象的多个Synchronized方法
        new SynchronizedDemo().showSynchronizedResult1();

        // 例2:多线程下同一对象的Synchronized方法和普通方法
        //new SynchronizedDemo().showSynchronizedResult2();

        // 例3:多线程下不同对象的Synchronized方法
        //new SynchronizedDemo().showSynchronizedResult3();

        // 例4:多线程下的多个static Synchronized方法
        //new SynchronizedDemo().showStaticSynchronizedResult4();
    }
}

class Sync{
    public synchronized void run1(){
        for (int i = 0; i < 5; i++){
            System.out.println("execute run1");
            sleepOneSec();
        }
    }

    public synchronized void run2(){
        for (int i = 0; i < 5; i++){
            System.out.println("execute run2");
            sleepOneSec();
        }
    }

    public void run3(){
        for (int i = 0; i < 5; i++){
            System.out.println("execute run3");
            sleepOneSec();
        }
    }

    public static synchronized void run4(){
        for (int i = 0; i < 5; i++){
            System.out.println("execute run4");
            sleepOneSec();
        }
    }

    public static synchronized void run5(){
        for (int i = 0; i < 5; i++){
            System.out.println("execute run5");
            sleepOneSec();
        }
    }

    private static void sleepOneSec(){
        try{
            Thread.sleep(1000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}
01-01 22:43