• 关于Java同步机制中synchronized同步方法


    Java的同步机制中被synchronized关键字修饰的有两种,一种是同步块,另一种是同步方法。现在直说同步方法
     
    在同步方法中,被synchronized关键字修饰的方法的作用域有两种:
            a.    作用域是某个实例内,synchronized Method(){ }可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象中有多个synchronized方法,只要一个线程访问了其中一个synchronized方法,其他线程不能同时访问这个对象中任何一个synchronized方法)。这时不同的对象实例中的synchronized方法是互不干扰的,也就是说,其他线程照样可以访问相同类的另一个对象实例中的synchronized方法。
                    也就是说,只被synchronized修饰的方法,作用域只在单个对象中,进程的同步机制只在单个对象中,不同对象中的synchronized方法是不相互干扰的
           Eg:
     public class ThreadSafeTest extends Thread implements Runnable {
        private static int num = 1;
    
        public ThreadSafeTest(String name) {
            setName(name);
        }
    
        public void run() {
            sell(getName());
            
        }
        
        private synchronized void sell(String name){
            if (num > 0) {
                System.out.println(name + ": 检测票数大于0");
                System.out.println(name + ": \t正在收款(大约5秒完成)。。。");
                try {
                    Thread.sleep(5000);
                    System.out.println(name + ": \t打印票据,售票完成");
                    num--;
                    printNumInfo();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println(name+": 没有票了,停止售票");
            }
        }
    
        private void printNumInfo() {
            System.out.println("系统:当前票数:" + num);
            if (num < 0) {
                System.out.println("警告:票数低于0,出现负数");
            }
        }
    
        public static void main(String args[]) {
            try {
                new ThreadSafeTest("售票员李XX").start();
                Thread.sleep(2000);
                new ThreadSafeTest("售票员王X").start();
                
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    上述代码中同步方法只被synchronized修饰,所以这个同步方法只能用于单个对象中。
     
            运行的结果是:并没有达到线程间同步的目的
      
    b.    作用域是某个类的范围,这个时候方法就需要synchronized static来修饰了。synchronized static Method(){ }用于防止多个线程同时访问这个类中的synchronized static方法,它是对类的所有对象实例起作用
                也就是说,某个方法被synchronized static修饰后,这个方法就对所有的对象实例起作用了,只要有一个对象实例调用了该方法,其他的对象实例只能等该方法解锁后才能调用该方法,从而起到线程之间的同步问题。
    Eg:
     把上述代码的sell()方法改为synchronized static,printNumInfo()改为static后就可以实现线程同步问题了
     public class ThreadSafeTest extends Thread implements Runnable {
        private static int num = 1;
    
        public ThreadSafeTest(String name) {
            setName(name);
        }
    
        public void run() {
            sell(getName());
            
        }
        
        private synchronized static void sell(String name){
            if (num > 0) {
                System.out.println(name + ": 检测票数大于0");
                System.out.println(name + ": \t正在收款(大约5秒完成)。。。");
                try {
                    Thread.sleep(5000);
                    System.out.println(name + ": \t打印票据,售票完成");
                    num--;
                    printNumInfo();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println(name+": 没有票了,停止售票");
            }
        }
    
        private static void printNumInfo() {
            System.out.println("系统:当前票数:" + num);
            if (num < 0) {
                System.out.println("警告:票数低于0,出现负数");
            }
        }
    
        public static void main(String args[]) {
            try {
                new ThreadSafeTest("售票员李XX").start();
                Thread.sleep(2000);
                new ThreadSafeTest("售票员王X").start();
                
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

     运行的结果达到了线程间的同步

    注意:synchronized关键字不能继承,也就是说,基类的方法synchronized f(){ }在继承类中不自动生成synchronized f() { },而变成了f() { }。继承类需要你显示的制定他的某个方法是synchronized方法。

  • 相关阅读:
    solr开发从查询结果集中获取对象数据
    solr开发,提交索引数据的几种方式
    初识SolrJ开发, schema.xml的配置与服务初始化.
    实例介绍,如何在开发中将各层日志归类输出.
    springmvc整合redis架构搭建实例
    面试求职中你需要了解的Java面向对象
    整合Solr到Tomcat服务器,并配置IK分词
    formValidator输入验证、异步验证实例 + licenseImage验证码插件实例应用
    SpringMVC整合Mongodb开发,高级操作
    SpringMVC整合Mongodb开发 架构搭建
  • 原文地址:https://www.cnblogs.com/Skyar/p/3079418.html
Copyright © 2020-2023  润新知