• Java多线程--synchronized(一)


    synchronized关键字

    脏读问题

    package ch02.test1;
    /*
       脏读
     */
    public class PublicVar {
        private String name = "a";
        private String pwd = "aa";
    
        public void setValue(String name, String pwd) {
    
            try {
                this.name = name;
                Thread.sleep(5000);
    
                this.pwd = pwd;
                System.out.println("setValue method thread name = " + Thread.currentThread().getName()
                        + "name=" + this.name + " pwd=" + this.pwd);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public void getValue() {
            System.out.println("getValue method thread name=" + Thread.currentThread().getName()
                +"name=" + this.name + " pwd=" + this.pwd);
        }
    }
    
    class MyThread extends Thread {
        private PublicVar publicVar;
    
        public MyThread(PublicVar publicVar) {
            this.publicVar = publicVar;
        }
    
        @Override
        public void run() {
            super.run();
            this.publicVar.setValue("b","bb");
        }
    }
    
    class Test {
        public static void main(String[] args) {
            try {
                PublicVar publicVar = new PublicVar();
                MyThread myThread = new MyThread(publicVar);
                myThread.start();
                Thread.sleep(200);
    
                publicVar.getValue();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

    output:

    getValue method thread name=mainname=b pwd=aa
    setValue method thread name = Thread-0name=b pwd=bb
    
    • 脏读的原因
      getValue()方法不同步

    • 脏读的解决
      用synchronized关键字修饰getValue()方法

    • 当线程A调用anyObject对象的synchronized方法X时,A线程就获得了对象锁。此时:

    1. 其他线程必须等待A线程执行完X方法才能执行X方法,以及anyObject对象的其他synchronized方法
    2. 其他线程调用anyObject对象的非synchronized方法不受影响

    synchronized锁重入

    • 什么是锁重入
      使用synchronized时,当一个线程得到一个对象锁后,它再次请求对象锁是可以获得对象锁的。
      简而言之,就是自己可以再次获得自己的内部锁
    • 如果没有锁重入,会导致死锁
    package ch02.test2;
    /*
        可重入锁
     */
    public class Service {
        public synchronized void service1() {
            service2();
            System.out.println("service1");
        }
        public synchronized void service2() {
            service3();
            System.out.println("service2");
        }
        public synchronized void service3() {
            System.out.println("service3");
        }
    }
    
    class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            new Service().service1();
        }
    }
     class Test {
         public static void main(String[] args) {
             MyThread myThread = new MyThread();
             myThread.start();
         }
     }
    

    output:

    service3
    service2
    service1
    

    一些结论

    • 当存在继承关系时,子类可以通过“可重入锁”调用父类的同步方法。
    • 出现异常,锁自动释放
    • 同步不可以继承

    作者:lykxbg —— 来一块小饼干

    出处:http://www.cnblogs.com/lykxbg/

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    FZU2150 Fire Game
    POJ3414 Pots
    POJ3087 Shuffle'm Up
    POJ3126 Prime Path
    POJ1426 Find The Multiple
    POJ3279 Fliptile
    甘特图实用技巧——项目进度一目了然!
    连设计图都不会画,你还想做“系统架构师”?
    java中list和map的底层实现原理
    redis四种部署方式
  • 原文地址:https://www.cnblogs.com/lykxbg/p/13648224.html
Copyright © 2020-2023  润新知