码迷,mamicode.com
首页 > 编程语言 > 详细

JAVA并发编程:synchronized及其实现原理

时间:2019-04-14 09:56:54      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:简单   png   ack   font   ted   并发   而不是   http   没有   

一、synchronized的基本使用

  synchronized是Java中解决并发问题的一种最常用的方法,也就最简单的一种方法。synchronized的作用有以下三个:

(1)确保线程互斥的访问同步代码

(2)保证共享变量的修改能及时可见

(3)有效解决重排序问题

从语法上将,synchronized总用有三种用法:

(1)修饰普通方法

(2)修饰静态方法

(3)修饰静态代码块

1、没有同步的情况:

  • 代码段1
    public class NoSynchronized {
    
        public void method1() {
            System.out.println("Method 1 start");
            try {
                System.out.println("Method 1 execute");
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Method 1 end");
        }
    
        public void method2() {
            System.out.println("Method 2 start");
            try {
                System.out.println("Method 2 execute");
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Method 2 end");
        }
    
        public static void main(String[] args) {
            final NoSynchronized bean = new NoSynchronized();
    
            new Thread(new Runnable() {
                public void run() {
                    bean.method1();
                }
            }).start();
    
            new Thread(new Runnable() {
                public void run() {
                    bean.method2();
                }
            }).start();
        }
    }

     执行结果如下,线程1和线程2同时进入执行状态,线程2要比线程1快,所以线程2先执行完成,这个过程线程1和线程2是同时执行的。

技术图片

2、对普通方法同步

  •  代码段二
    public class NormalMethodSynchronized {
    
        public synchronized void method1() {
            System.out.println("Method 1 start");
            try {
                System.out.println("Method 1 execute");
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Method 1 end");
        }
    
        public synchronized void method2() {
            System.out.println("Method 2 start");
            try {
                System.out.println("Method 2 execute");
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Method 2 end");
        }
    
        public static void main(String[] args) {
            final NormalMethodSynchronized bean = new NormalMethodSynchronized();
    
            new Thread(new Runnable() {
                public void run() {
                    bean.method1();
                }
            }).start();
    
            new Thread(new Runnable() {
                public void run() {
                    bean.method2();
                }
            }).start();
        }
    }

 执行结果如下,跟代码一比较,可以很明显看出,线程2需要等待线程1的method1执行完成才能执行method2方法。

 技术图片

3、静态方法(类)同步

  • 代码段3
    public class StaticMethodSynchronized {
        public static synchronized void method1() {
            System.out.println("Method 1 start");
            try {
                System.out.println("Method 1 execute");
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Method 1 end");
        }
    
        public static synchronized void method2() {
            System.out.println("Method 2 start");
            try {
                System.out.println("Method 2 execute");
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Method 2 end");
        }
    
        public static void main(String[] args) {
            final StaticMethodSynchronized bean1 = new StaticMethodSynchronized();
            final StaticMethodSynchronized bean2 = new StaticMethodSynchronized();
    
            new Thread(new Runnable() {
                public void run() {
                    bean1.method1();
                }
            }).start();
    
            new Thread(new Runnable() {
                public void run() {
                    bean2.method2();
                }
            }).start();
        }
    }

 执行结果如下,对静态方法的同步本质上是对类的同步(静态方法本质上是属于类的方法,而不是对象的方法),所以即使bean1和bean2属于不同的对象,但是他们都属于StaticMethodSynchronized类的实例,所以也只能顺序的执行method1和method2,不能并发执行。

技术图片

 

JAVA并发编程:synchronized及其实现原理

标签:简单   png   ack   font   ted   并发   而不是   http   没有   

原文地址:https://www.cnblogs.com/lynn16/p/10703775.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!