zoukankan      html  css  js  c++  java
  • java高并发synchronized学习

    1.synchronized的作用:同步方法支持一种简单的策略来防止线程干扰和内存一致性的错误:如果一个对象对多个线程可见,则对该对象的所有读取或写入都是通过同步方法来完成的。总的来说是能够在同一时候保证最多只有一个线程执行该段代码,以达到安全的效果。

    2.synchronized是java的关键字,被java语言原生支持,是最基本的互斥同步手段

    代码演示

    public class DisapperRequest1 implements  Runnable {
    static int k=0;
    static DisapperRequest1 disapperRequest1=new DisapperRequest1();
    @Override
    public void run() {
    for(int i=0;i<100000;i++)
    {
    k++;
    }
    }

    public static void main(String[] args) throws InterruptedException {
    Thread thread=new Thread(disapperRequest1);
    Thread thread1=new Thread(disapperRequest1);
    thread.start();
    thread1.start();
      /**join的意思是使得放弃当前线程的执行,并返回对应的线程,例如下面代码的意思就是:
             程序在main线程中调用t1线程的join方法,则main线程放弃cpu控制权,并返回t1线程继续执行直到线程t1执行完毕
             所以结果是t1线程执行完后,才到主线程执行,相当于在main线程中同步t1线程,t1执行完了,main线程才有执行的机会

    thread.join();
    thread1.join();
    System.out.println(k);
    }


    }
    join方法是通过调用线程的wait方法来达到同步的目的的。例如,A线程中调用了B线程的join方法,则相当于A线程调用了B线程的wait方法,在调用了B线程的wait方法后,A线程就会进入阻塞状态
    最后的结果总是小于或等于20W 这跟预期的结果不一样。count++看上去只有一个操作,实际上是有三个操作的1.读取count的值 2.讲count加1 3.将count的值加入内存
    当count的值还没有加入内存的时候count就已经读取了。这样就会造成线程不安全。

    3.Synchronized两种方法用法:对象锁:包括方法锁(默认锁对象为this当前的实例的对象)和同步代码块锁(自己指定锁对象)。类锁:指的是用Synchronized修饰的静态方法或者指定锁对象为class对象
    代码块形式要手动指定对象,方发锁形式:Synchronized修饰普通方法,锁对象默认为this

    代码块锁:isAlive方法判断线程是否存活
    public class SynchronizedObjectCodeBlock2 implements Runnable {
             static SynchronizedObjectCodeBlock2 instance=new SynchronizedObjectCodeBlock2();
        @Override
        public void run() {
            synchronized(this) {
                System.out.println(Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "运行结束");
            }
        }
    
        public static void main(String[] args) {
             Thread t1=new Thread(instance);
             Thread t2=new Thread(instance);
             t1.start();
             t2.start();
             while (t1.isAlive()||t2.isAlive())
             {
    
             }
             System.out.println("结束");
        }
    }
    当用两个锁的情况:当不是同一把锁的时候,可以并行运行
    public class SynchronizedObjectCodeBlock2 implements Runnable {
             static SynchronizedObjectCodeBlock2 instance=new SynchronizedObjectCodeBlock2();
             Object lock1=new Object();
             Object lock2=new Object();
        @Override
        public void run() {
            synchronized(lock1) {
                System.out.println(Thread.currentThread().getName()+"lock1");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "运行结束1");
            }
            synchronized(lock2) {
                System.out.println(Thread.currentThread().getName()+"lock2");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "运行结束2");
            }
        }
    
        public static void main(String[] args) {
             Thread t1=new Thread(instance);
             Thread t2=new Thread(instance);
             t1.start();
             t2.start();
             while (t1.isAlive()||t2.isAlive())
             {
    
             }
             System.out.println("结束");
        }
    }
    
    

    对象锁:Synchronized修饰普通的方法,默认锁对象为this

    package com.xiaoqiang.sychronized;
    
    public class SynchronizedObjectMethod3 implements Runnable {
    
        static SynchronizedObjectMethod3 instance=new SynchronizedObjectMethod3();
    
        @Override
        public void run() {
           method();
    
        }
    
        public static void main(String[] args) {
            Thread t1=new Thread(instance);
            Thread t2=new Thread(instance);
            t1.start();
            t2.start();
            while (t1.isAlive()||t2.isAlive())
            {
    
            }
            System.out.println("结束");
        }
    
        public synchronized  void method()
        {
            System.out.println(Thread.currentThread().getName()+"lock1");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "运行结束1");
        }
    }

    类锁:

    1.staic 类锁:假如不在method中加入staic修饰的话,两个不同的静态对象就会并行执行run方法

    package com.xiaoqiang.sychronized;
    
    public class SynchronizedClassStatic4 implements  Runnable {
        static  SynchronizedClassStatic4 instance1=new SynchronizedClassStatic4();
        static SynchronizedClassStatic4 instance2=new SynchronizedClassStatic4();
        @Override
        public void run() {
            method();
        }
    
        public static void main(String[] args) {
            Thread t1=new Thread(instance1);
            Thread t2=new Thread(instance2);
            t1.start();
            t2.start();
            while (t1.isAlive()||t2.isAlive())
            {
    
            }
            System.out.println("结束");
        }
    
        public synchronized  void method()
        {
            System.out.println(Thread.currentThread().getName()+"lock1");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "运行结束1");
        }
    }

    如果用 static 修饰method方法的话就会串行进行

    package com.xiaoqiang.sychronized;
    
    public class SynchronizedClassStatic4 implements  Runnable {
        static  SynchronizedClassStatic4 instance1=new SynchronizedClassStatic4();
        static SynchronizedClassStatic4 instance2=new SynchronizedClassStatic4();
        @Override
        public void run() {
            method();
        }
    
        public static void main(String[] args) {
            Thread t1=new Thread(instance1);
            Thread t2=new Thread(instance2);
            t1.start();
            t2.start();
            while (t1.isAlive()||t2.isAlive())
            {
    
            }
            System.out.println("结束");
        }
    
        public  static synchronized  void method()
        {
            System.out.println(Thread.currentThread().getName()+"lock1");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "运行结束1");
        }
    }
    2.。*.class 类锁
    同一个类锁的实现
    package com.xiaoqiang.sychronized;
    
    public class SynchronizedClassClass5 implements Runnable {
        static  SynchronizedClassClass5 instance1=new SynchronizedClassClass5();
        static SynchronizedClassClass5 instance2=new SynchronizedClassClass5();
        @Override
        public void run() {
            method();
        }
    
        public static void main(String[] args) {
            Thread t1=new Thread(instance1);
            Thread t2=new Thread(instance2);
            t1.start();
            t2.start();
            while (t1.isAlive()||t2.isAlive())
            {
    
            }
            System.out.println("结束");
        }
    
       private  void method() {
           synchronized (SynchronizedClassClass5.class) {
               System.out.println(Thread.currentThread().getName() + "lock1");
               try {
                   Thread.sleep(5000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               System.out.println(Thread.currentThread().getName() + "运行结束1");
           }
       }
    }
    
    

    4.Synchronized的核心思想:

    1.一把锁只能同时被一个线程获取,没有拿到锁的线程必须等待。

    2.每个实例都对应自己的一把锁,不同实例之间互不影响。例外:锁对象是*.class或者用Synchronized修饰的是static方法时,所有对象都共用同一把锁

    3.无论是正常运完毕或者方法抛出异常,都会释放锁。

    5.Synchronized的性质

    1.可重入性:指的是同一线程外层函数获取到锁后之后,内层函数可以直接再次获取该锁。

    好处:避免死锁,提高封装性。

    粒度(范围):线程而非调用

    2.不可中断性:一旦这个锁已经被别人获得了,如果我还想获得,就必须等待或者阻塞,直到别的线程释放这个锁。如果别人永远不释放锁,那么只能永远的等待下去。

    6.Synchronized的缺点:

    效率低:锁的释放情况少,试图获得锁的时候不能设置超时,不能中断一个正试图获得锁的线程。

    不够灵活:加锁和释放锁的时机单一,每个锁仅有单一的条件,可能是不够的。

    无法知道是否成功获取到锁



  • 相关阅读:
    Python-函数
    Python-运数符
    Python-条件判断
    Python-变量
    移动端页面布局的那些事儿
    关于ie7下display:inline-block;不支持的解决方案
    SuperSlidev2.1 轮播图片和无缝滚动
    解决xmapp中Apache端口号占用问题
    npm 常用命令详解
    python函数总结
  • 原文地址:https://www.cnblogs.com/socketqiang/p/10819208.html
Copyright © 2011-2022 走看看