zoukankan      html  css  js  c++  java
  • synchronized使用

    一、synchronized加锁方式

     synchronized可以使多线程同步运行。

    synchronized的使用时需要配合对象,即每一个synchronized修饰的方法或代码块都会配备一个对象,这个对象可以是实例对象也可以是类对象,类锁本质上也是Class类的实例对象。所以每一个synchronized都会跟一个实例对象对应。

    synchronized修饰方法时,默认加的是当前对象实例的锁;修饰静态方法时默认加的是当前类的类对象的锁。修饰代码块和静态代码块,书写方式一样,不同的是所加的对象锁。

    互斥规则:

    1、当一个线程访问某对象的synchronized方法或代码块时,其他线程可以访问非synchronized方法或代码块,不会阻塞。

    2、当锁是同一对象实例时,一个线程访问该对象的synchronized方法或代码块时,其他线程访问该对象的synchronized方法或代码块时,会被阻塞。

    3、同一类的不同实例对象的对象锁互不干扰。

    4、类锁也是一种特殊的对象锁,第2条同样适用,适用于静态方法和加了类锁的代码块。

    5、类锁和对象锁互不干扰。

    二、加锁实例

    import lombok.SneakyThrows;
    
    public class SynchThread implements Runnable {
        @SneakyThrows
        @Override
        public void run() {
            if("static_method".equals(Thread.currentThread().getName())){
                synchronizedStaticMethod();
            }else if("no_static_method".equals(Thread.currentThread().getName())){
                synchronizedMethod();
            }else if ("static_block".equals(Thread.currentThread().getName())){
                synchronized(SynchThread.class){
                    System.out.println(Thread.currentThread().getName()+" :synchronized静态代码块start.....");
                    System.out.println(Thread.currentThread().getName()+" :synchronized静态代码块sleep.....");
                    Thread.sleep(2000);
                    System.out.println(Thread.currentThread().getName()+" :synchronized静态代码块voer!!!");
                }
            }else if ("no_static_block".equals(Thread.currentThread().getName())){
                synchronized (this){
                    System.out.println(Thread.currentThread().getName()+" :synchronized代码块start.....");
                    System.out.println(Thread.currentThread().getName()+" :synchronized代码块sleep.....");
                    Thread.sleep(2000);
                    System.out.println(Thread.currentThread().getName()+" :synchronized代码块voer!!!");
                }
            }
    
    
        }
    
    
        @SneakyThrows
        public synchronized void synchronizedMethod(){
            System.out.println(Thread.currentThread().getName()+" :synchronized方法start....");
            System.out.println(Thread.currentThread().getName()+" :synchronized方法sleep....");
            Thread.sleep(2000);
            System.out.println(Thread.currentThread().getName()+" :synchronized方法voer!!!");
        }
    
        @SneakyThrows
        public synchronized static void synchronizedStaticMethod(){
            System.out.println(Thread.currentThread().getName()+" :synchronized静态方法start....");
            System.out.println(Thread.currentThread().getName()+" :synchronized静态方法sleep....");
            Thread.sleep(2000);
            System.out.println(Thread.currentThread().getName()+" :synchronized静态方法voer!!!");
        }
    }

    测试代码:

    public class SynchThreadDome {
        public static void main(String[] args){
            Runnable synchRun = new SynchThread();
    
            Thread thread1 = new Thread(synchRun,"static_method");
            Thread thread2 = new Thread(synchRun,"no_static_method");
            Thread thread3 = new Thread(synchRun,"static_block");
            Thread thread4 = new Thread(synchRun,"no_static_block");
    
            thread1.start();
            thread2.start();
            thread3.start();
            thread4.start();
    
        }
    }

    结果:

    static_method :synchronized静态方法start....
    static_method :synchronized静态方法sleep....
    no_static_method :synchronized方法start....
    no_static_method :synchronized方法sleep....
    static_method :synchronized静态方法voer!!!
    static_block :synchronized静态代码块start.....
    static_block :synchronized静态代码块sleep.....
    no_static_method :synchronized方法voer!!!
    no_static_block :synchronized代码块start.....
    no_static_block :synchronized代码块sleep.....
    static_block :synchronized静态代码块voer!!!
    no_static_block :synchronized代码块voer!!!

    上述结果可以看出:

    1、静态方法(代码块)和非静态方法(代码块)的执行互不干扰。

    2、静态方法和静态代码块之间相互阻塞;非静态方法和非静态代码块之间相互阻塞;

    因为静态方法和静态代码块加的是this锁;非静态方法和非静态代码块加的是类锁(SynchThread.class)。

    总结:从一个更加广义的角度看待锁的机制,上了同一个锁的多个线程,不管线程调用的是不是同一段逻辑,都会形成阻塞;未上相同锁的多个线程,相互运行不相干。

    如下:

    package test.thread;
    
    public class TestLock {
        public static void main(String[] args) {
            String str = new String();
            System.out.println("aaa开始");
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    synchronized (str) {
                        for (int i = 0; i < 100; i++) {
                            System.out.println("aaaa"+i);
                        }
                    }
                }
            }).start();
            
            System.out.println("bbb开始");
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    synchronized (str) {
                        for (int i = 0; i < 100; i++) {
                            System.out.println("bbbb"+i);
                        }
                    }
                }
            }).start();
            
        }
    }

    以上代码会在aaa0~aaa99输出完成后,在输出bbb0~bbb99.

    就算这个世道烂成一堆粪坑,那也不是你吃屎的理由
  • 相关阅读:
    BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )
    BZOJ 2134: 单选错位( 期望 )
    BZOJ 1030: [JSOI2007]文本生成器( AC自动机 + dp )
    BZOJ 2599: [IOI2011]Race( 点分治 )
    BZOJ 3238: [Ahoi2013]差异( 后缀数组 + 单调栈 )
    ZOJ3732 Graph Reconstruction Havel-Hakimi定理
    HDU5653 Bomber Man wants to bomb an Array 简单DP
    HDU 5651 xiaoxin juju needs help 水题一发
    HDU 5652 India and China Origins 并查集
    HDU4725 The Shortest Path in Nya Graph dij
  • 原文地址:https://www.cnblogs.com/whalesea/p/12970853.html
Copyright © 2011-2022 走看看