美文网首页
Synchronized基本使用

Synchronized基本使用

作者: 远o_O | 来源:发表于2017-07-30 14:55 被阅读9次

    一、概述

    • 在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化(偏向锁、轻量级锁CAS)之后,有些情况下它并不那么重了。
    • Java SE1.6为了减少获得锁和释放锁所带来的性能消耗,引入了“偏向锁”和“轻量级锁”,所以在Java SE1.6里锁一共有四种状态,无锁状态,偏向锁状态,轻量级锁状态和重量级锁状态,它会随着竞争情况逐渐升级。锁可以升级但不能降级,意味着偏向锁升级成轻量级锁后不能降级成偏向锁。这种锁升级却不能降级的策略,目的是为了提高获得锁和释放锁的效率。

    二、用法

    • 实例方法:锁住整个方法,整个方法都需要同步。
    • 静态方法:锁住整个方法,整个方法都需要同步。访问,所有对象实例上的线程都需要同步,这个同步静态方法,已经和类绑定。
    • 实例方法中的同步块:只锁同步块,方法中其余地方线程可以并发执行。
    • 静态方法中的同步块:只锁同步块,方法中其余地方线程可以并发执行。

    三、注意事项

    • 静态方法中的同步块,只能锁class对象synchronized (SuspendTest.class)和静态引用成员变量,不能锁非静态实例对象例如:synchronized (this),编译不通过。

    • 实例方法中的同步块,既能锁住class对象和静态引用成员变量,也可以锁对象实例。

      • 锁住class对象或静态引用成员变量:所有对象实例上面的线程都需要同步执行。访问,所有对象实例上的线程都需要同步,这个同步静态代码块,已经和类绑定。
      • 锁住对象实例: 不同对象实例上面的线程互不干扰,可以并发执行。
    • 总之,只要synchronized和Class对象或者static扯上关系,访问,所有对象实例上的线程都需要同步。

    四、测试代码

    package test;
    
    import java.util.concurrent.LinkedTransferQueue;
    
    public class SuspendTest {
    
        private static void getSome(){
            //静态同步块,只能锁class,不可以锁实例
            synchronized (SuspendTest.class){
                System.out.println(Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        private void setSome(){
            //只有同步块需要线程同步执行,同步口外面的可以并发执行
            //System.out.println(Thread.currentThread().getName());
            synchronized (this){
                System.out.println(Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public static void main(String[] args) {
            SuspendTest suspendTest = new SuspendTest();
            suspendTest.test();
            //suspendTest.testStatic();
            SuspendTest suspendTest1 = new SuspendTest();
            suspendTest1.test();
            //suspendTest1.testStatic();
        }
    
        public void test(){
            new Thread(()->{setSome();}).start();
            new Thread(()->{setSome();}).start();
            new Thread(()->{setSome();}).start();
        }
    
        public static void testStatic(){
            new Thread(()->{getSome();}).start();
            new Thread(()->{getSome();}).start();
            new Thread(()->{getSome();}).start();
        }
    }
    
    

    相关文章

      网友评论

          本文标题:Synchronized基本使用

          本文链接:https://www.haomeiwen.com/subject/vzbhlxtx.html