Synchronize的学习

原文链接:https://www.cnblogs.com/paddix/p/5367116.html

基本介绍:
Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。
主要作用:

  1. 修饰普通方法
  2. 修饰静态方法
  3. 修饰代码块

代码演示:

1.无Synchronized修饰

public class SyTestDemo {
    public void methods1(){
        System.out.println("methods1.start..");
        try {
            System.out.println("methods1.excute..");
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("methods1.end..");
    }
    public void methods2(){
        System.out.println("methods2.start.." );
        try {
            System.out.println("methods2.excute..");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("methods2.end..");
    }
    public static void main(String[] args) {
        SyTestDemo testDemo = new SyTestDemo();

        new Thread(new Runnable() {
            @Override
            public void run() {
                testDemo.methods1();
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                testDemo.methods2();
            }
        }).start();
    }
}

结果:
输入1
可以看出线程2在线程1结束前先结束。没有达到线程1运行完然后线程2在运行的目的。

2.修饰普通方法

代码演示

public class SyTestDemo2 {
	//方法块1
    public synchronized void methods1(){
        System.out.println("methods1.start..");

        try {
            System.out.println("methods1.excute..");
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("methods1.end..");
    }
    //方法块2
    public synchronized void methods2(){
        System.out.println("methods2.start..");

        try {
            System.out.println("methods2.excute..");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("methods2.end..");
    }

    public static void main(String[] args) {
        SyTestDemo2 syTestDemo2 = new SyTestDemo2();

        new Thread(new Runnable() {
            @Override
            public void run() {
                syTestDemo2.methods1();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                syTestDemo2.methods2();
            }
        }).start();
    }
}

结果:
结果2
可以看出结果中是线程1先执行完然后线程2再完成。没有并发执行的情况产生。

3.修饰静态方法

代码演示:

public class SyTestDemo2 {
	//静态方法1
    public static synchronized void methods1(){
        System.out.println("methods1.start..");

        try {
            System.out.println("methods1.excute..");
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("methods1.end..");
    }
    //静态方法2
    public static synchronized void methods2(){
        System.out.println("methods2.start..");

        try {
            System.out.println("methods2.excute..");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("methods2.end..");
    }

    public static void main(String[] args) {
        SyTestDemo2 syTestDemo2 = new SyTestDemo2();
        
        new Thread(new Runnable() {
            @Override
            public void run() {
                syTestDemo2.methods1();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                syTestDemo2.methods2();
            }
        }).start();
    }
}

结果:
演示3
修饰静态方法相当于修饰类。因为静态方法是类的方法而不是对象的方法。所以输出结果依旧是线程1先执行完,然后线程2执行完,没有并发执行。

4.修饰对象。

public class SyTestDemo3 {
    //方法块1
    public void methods1(){
        System.out.println("methods1.start..");
        synchronized (this){
            System.out.println("methods1.excute..");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("methods1.end..");
    }
    //方法块2
    public void methods2(){
        System.out.println("methods2.start..");
        synchronized (this){
            System.out.println("methods2.excute..");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("method2.end..");
    }

    public static void main(String[] args) {
        SyTestDemo3 syTestDemo3 = new SyTestDemo3();

        new Thread(new Runnable() {
            @Override
            public void run() {
                syTestDemo3.methods1();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                syTestDemo3.methods2();
            }
        }).start();
    }
}

结果:
结果4
可以从结果中看出:虽然线程1和线程2都进入方法执行。但是线程2在进入同步块之前,需要等待线程1中同步块执行完成。

参考博客:Sychronized的学习和底层实现

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章