网上看到很多对关键字synchronized继承性的描述只有一句"关键字synchronized不能被继承",并没有描述具体场景,于是自己做了以下测试。

//父类

public class Super {

static Logger logger = Logger.getLogger(Super.class);

// 同步方法
    @SuppressWarnings("static-access")
    public synchronized void testMothed() {
         try {
                Thread.currentThread().sleep(5000);//休眠5秒。
         } catch (InterruptedException e) {
                e.printStackTrace();
         }
          logger.info(Thread.currentThread().getName() + "," + this);
    }

}

//子类1

public class Sub1 extends Super {

// 不重写父类的同步方法
}

//子类2

public class Sub2 extends Super {

// 重写父类的同步方法,但不加synchronized。

@SuppressWarnings("static-access")
    public void testMothed() {
        try {
               Thread.currentThread().sleep(3000);//为区别与父类中休眠时间,改为3秒。
        } catch (InterruptedException e) {
                  e.printStackTrace();
        }
        logger.info(Thread.currentThread().getName() + "," + this);
    }
}

//测试类

public class SynchronizedTest {

static Logger logger = Logger.getLogger(SynchronizedTest.class);

public static void main(String[] args) throws Exception {
            // 子类对象1
            final Sub1 sub1 = new Sub1();
            final int count = 5;
            // 创建count个不同线程,调用子类对象1同一方法
            for (int i = 0; i < count; i++) {
                   new Thread() {
                           public void run() {
                                  sub1.testMothed();
                           }
                    }.start();
              }

// 让上面所有子线程有足够时间执行结束
             TimeUnit.SECONDS.sleep((count+1)*5);

logger.info("===============================================");

// 子类对象2
             final Sub2 sub2 = new Sub2();
             // 创建count个不同线程,调用子类对象2同一方法
             for (int i = 0; i < count; i++) {
                     new Thread() {
                          public void run() {
                               sub2.testMothed();
                         }
                     }.start();
              }
    }
   
}

执行结果:

12:40:18,043 [INFO]----> Thread-0,java_lang.thread_synchronized.Sub1@86f241
 12:40:23,044 [INFO]----> Thread-4,java_lang.thread_synchronized.Sub1@86f241
 12:40:28,044 [INFO]----> Thread-3,java_lang.thread_synchronized.Sub1@86f241
 12:40:33,044 [INFO]----> Thread-2,java_lang.thread_synchronized.Sub1@86f241
 12:40:38,045 [INFO]----> Thread-1,java_lang.thread_synchronized.Sub1@86f241
 12:40:43,044 [INFO]----> ===============================================
 12:40:46,045 [INFO]----> Thread-6,java_lang.thread_synchronized.Sub2@15dfd77
 12:40:46,045 [INFO]----> Thread-7,java_lang.thread_synchronized.Sub2@15dfd77
 12:40:46,045 [INFO]----> Thread-5,java_lang.thread_synchronized.Sub2@15dfd77
 12:40:46,046 [INFO]----> Thread-8,java_lang.thread_synchronized.Sub2@15dfd77
 12:40:46,046 [INFO]----> Thread-9,java_lang.thread_synchronized.Sub2@15dfd77

从上面可以看出,

不同线程对子类Sub1的同一对象sub1,调用testMothed,有同步效果,分别进入该方法,分别等待5秒。(红色与红色时间差)

不同线程对子类Sub2的同一对象sub2,调用testMothed,没有同步效果,所有线程同时进入该方法并同时等待3秒(蓝色到绿色时间差),然后同时执行(绿色时间一样)。

因此,对"关键字synchronized不能被继承",完整描述应该是:

1、子类继承父类时,如果没有重写父类中的同步方法,子类同一对象,在不同线程并发调用该方法时,具有同步效果。

2、子类继承父类,并且重写父类中的同步方法,但没有添加关键字synchronized,子类同一对象,在不同线程并发调用该方法时,不再具有同步效果,这种情形即是"关键字synchronized不能被继承"的转述。(貌似很多人在这一点上存在疑惑)。

关于“关键字synchronized不能被继承”的一点理解的更多相关文章

  1. 对synchronized的一点理解

    一.synchronized的使用(一).synchronized同步方法1. “非线程安全”问题存在于“实例变量”中,如果是方法内部的私有变量,则不存在“非线程安全”问题.2. 如果多个线程共同访问 ...

  2. iOS 的一点理解(一) 代理delegate

    做了一年的iOS,想记录自己对知识点的一点理解. 第一篇,想记录一下iOS中delegate(委托,也有人称作代理)的理解吧. 故名思议,delegate就是代理的含义, 一件事情自己不方便做,然后交 ...

  3. RxSwift 入坑好多天 - 终于有了一点理解

    一.前言 江湖上都在说现在就要赶紧学 swift 了,即将是 swift 的天下了.在 api 变化不大的情况下,swift 作为一门新的语言,集众家之所长,普通编码确实比 oc 要好用的多了 老早就 ...

  4. 一张图讲解对象锁和关键字synchronized修饰方法

    每个对象在出生的时候就有一把钥匙(监视器),那么被synchronized 修饰的方法相当于给方法加了一个锁,这个方法就可以进行同步,在多线程的时候,不会出现线程安全问题. 下面通过一张图片进行讲解: ...

  5. 新手向-同步关键字synchronized对this、class、object、方法的区别

    synchronized的语义 实验 分析 在看源代码时遇到多线程需要同步的时候,总是会看见几种写法,修饰方法.修饰静态方法.synchronized(Xxx.class).synchronized( ...

  6. opencv笔记5:频域和空域的一点理解

    time:2015年10月06日 星期二 12时14分51秒 # opencv笔记5:频域和空域的一点理解 空间域和频率域 傅立叶变换是f(t)乘以正弦项的展开,正弦项的频率由u(其实是miu)的值决 ...

  7. 对socket的一点理解笔记

    需要学web service,但是在视频中讲解到了socket套接字编程.以前貌似课上老师有提过,只是没用到也感觉乏味.现在遇到,自己看了些博客和资料.记录一点理解,不知正确与否. 首先说这个名字,叫 ...

  8. 关于web开发的一点理解

    对于web开发上的一点理解 1 宏观上的一点理解 网页从请求第地址 到获得页面的过程:从客户端(浏览器)通过地址 从soket把请求报文封装发往服务端   服务端通过解析报文并处理报文最后把处理的结果 ...

  9. 同步关键字synchronized

    同步关键字synchronized 同步关键字synchronized使用简洁,代码可维护性好.在JDK6中,性能也比早期的JDK有很大的改进.如果可以满足程序要求,应该首先考虑这种同步方式. 关键字 ...

随机推荐

  1. android高仿抖音、点餐界面、天气项目、自定义view指示、爬取美女图片等源码

    Android精选源码 一个爬取美女图片的app Android高仿抖音 android一个可以上拉下滑的Ui效果 android用shape方式实现样式源码 一款Android上的新浪微博第三方轻量 ...

  2. 接口测试时返回的响应报json错误

    问题: 测试接口时,传入错误数据,最开始对于错误数据也返回了json数据的响应:后来传入错误数据,接口突然就没有返回json数据,通过在出错的代码之前进行打印,发现接口报500了 检查错误的方法1:在 ...

  3. H5页面如何引入vConsole

    vConsole github地址vConsole 是腾讯开源的项目,这就简单的介绍一下使用 使用npm引入vconsole.min.js下载 vConsole 的最新版本.(不要直接下载 dev 分 ...

  4. Docker的部署安装(CentOS)-by paymob

    环境准备 通过命令查看系统版本和内核版本等信息 [gmuser@--- ~]$ cat /etc/redhat-release CentOS Linux release (Core) [gmuser@ ...

  5. mac命令日常总结

    查看某个端口被占用 lsof -i tcp:8080 kill进程: 找到进程的PID,使用kill命令:kill -9 716(PID) date 显示系统日期 mkdir xx 创建xx目录 rm ...

  6. C++笔试常见问题

    C++提供的编译预处理功能主要有以下三种: 宏定义 文件包含 条件编译 预编译又称为预处理 , 是做些代码文本的替换工作.处理#开头的指令 , 比如拷贝 #include包含的文件代码, #defin ...

  7. Nginx笔记总结四:Nginx连接PHP5.4

    location ~ .*\.(php)?${ expires -ls; try_file $uri=404; fastcgi_split_path_info ~(.+\.php)(/.+)$; in ...

  8. tf.estimator

    estimator同keras是tensorflow的高级API.在tensorflow1.13以上,estimator已经作为一个单独的package从tensorflow分离出来了.estimat ...

  9. 吴裕雄--python学习笔记:sqlite3 模块的使用与学生信息管理系统

    import sqlite3 cx = sqlite3.connect('E:\\student3.db') cx.execute( '''CREATE TABLE StudentTable( ID ...

  10. SpringMVC之转发重定向

    package com.tz.controller; import org.springframework.stereotype.Controller; import org.springframew ...