zoukankan      html  css  js  c++  java
  • 高并发详解---synchronized 并发关键字

    Synchronized作用:

    官方:同步方法支持一种简单的策略来方式线程干扰和内存一致性错误,如果一个对象对多个线程可见,则对该对象变量所有的读取和写入都是同步方法完成的。

    通俗:能够保证同一时刻最多只有一个线程执行改代码,以保证并发安全效果。

    Synchronized地位:

    关键字,是基本的同步互斥手段,并发编程必学内容。

    不用并发的后果:

    多线程情况下出现结果跟预期不符,我们称作线程不安全,例如下面结果不是我们想要的20000

    public class DisAppearRequest1 implements Runnable{
        static  int i = 0;
        static DisAppearRequest1 instance = new DisAppearRequest1();
    
        public static void main(String[] args) throws Exception{
            Thread thread1 = new Thread(instance);
            Thread thread2 = new Thread(instance);
            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();
            System.out.println(i);
        }
    
        public void run() {
            for(int j=0;j<10000;j++){
                i++;
            }
        }
    }
    

    count++ ;它看上去只是一个操作,实际上包含了三个动作:

    1. 读取 count。
    2. 将 count 加1。
    3. 将 count的值写入到内存中。假设count为1,线程A进入该方法进行加1操作后count变成2,还未写入内存。线程B进入该方法      对读取的count依旧为1,进行加1后count也是2,因此无论是A还是B写入内存的数值都是2,预期中本来应该为3的数值变成了2

     用法介绍

    对象锁:包括方法锁(默认锁对象为this当前实例对象)和同步代码块锁(自己指定锁对象)
    类锁:指synchronized修饰静态的方法或指定锁为Class对象。

    几种情况:

    •  两个线程同时访问同一个对象(同一个instance)的同步方法(Synchronized修饰),顺序执行,线程一执行结束,线程2执行,是对象锁的方法锁
    • 两个对象访问的是两个对象(两个实例)的同步方法,同步不起作用,相当于两个锁,每个实例有自己的锁,所以两个线程会是同时开始同时结束
    • 两个线程访问的是synchronized的静态方法,顺序执行,是类锁的static synchronized
    • 同时访问同步方法和非同步方法(一个被sychronized,一个没有),(线程是同一实例,线程一访问同步线程2访问非同步) , 两个线程同时执行,因为同步方法对非同步方法不会有任何影响
    • 访问同一个对象的不同的普通同步方法,因为是同一个对象,不同的同步方法默认都是this即当前的实例,所以存在线程等待释放,所以会是同步,是对象锁的同步方法 方法锁
    • 同时访问static synchronized 和非静态synchronized ,线程同时执行,他们所指定的锁对象是不一样的(没有加static的锁是this实例本身,加了static时锁是类锁,他背后的锁是.class对象)
    • 如果同时访问同步方法中包含了非同步方法,我觉得是同步的,因为入口同步方法不是放资源,也不能进入非同步方法,代码执行也是线程安全的 , (((但是老师解释一旦进入非同步方法就灭有锁了))

     

    方法抛出异常后会释放锁吗(一旦抛出异常,第二个线程立即获得锁,立刻进入同步方法,意味着锁已经释放):不需要我们主动去释放锁,抛出异常后jvm释放了锁。

     这些信息都是从慕课网上听来的

  • 相关阅读:
    Android屏幕适配
    设计模式学习心得
    C语言中的作用域、链接属性与存储属性
    二级指针删除单向链表
    C++编程风格
    python中index、slice与slice assignment用法
    lua_pcall与lua_call之间的区别
    lua-C++ userdata使用
    lua中调用C++函数
    C++中为什么有时要使用extern "C"
  • 原文地址:https://www.cnblogs.com/wygm/p/12201145.html
Copyright © 2011-2022 走看看