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.

    就算这个世道烂成一堆粪坑,那也不是你吃屎的理由
  • 相关阅读:
    MFC编程入门之二十八(常用控件:列表视图控件List Control上)
    Discuz X1.5 利用添加好友处存储xss进行蠕虫worm扩散
    全民wifi钓鱼来临----agnes安卓wifi钓鱼神器介绍
    自改xss小平台上线
    谈网页游戏外挂之用python模拟游戏(热血三国2)登陆
    thinkpad t440p 解决无线网卡驱动
    编写php拓展实例--slime项目(用户登录会话类)
    用Tupper自我指涉公式造图
    一首歌
    rtx信息泄漏利结合弱口令导致被批量社工思路
  • 原文地址:https://www.cnblogs.com/whalesea/p/12970853.html
Copyright © 2011-2022 走看看