`
琼海溜
  • 浏览: 18574 次
  • 性别: Icon_minigender_1
  • 来自: 海口
社区版块
存档分类
最新评论

关于“关键字synchronized不能被继承”的一点理解。

    博客分类:
  • Java
阅读更多

网上看到很多对关键字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();
              }
    }
   
}

 

 

执行结果:

 

2013-12-03 12:40:18,043 [INFO]----> Thread-0,java_lang.thread_synchronized.Sub1@86f241
2013-12-03 12:40:23,044 [INFO]----> Thread-4,java_lang.thread_synchronized.Sub1@86f241
2013-12-03 12:40:28,044 [INFO]----> Thread-3,java_lang.thread_synchronized.Sub1@86f241
2013-12-03 12:40:33,044 [INFO]----> Thread-2,java_lang.thread_synchronized.Sub1@86f241
2013-12-03 12:40:38,045 [INFO]----> Thread-1,java_lang.thread_synchronized.Sub1@86f241
2013-12-03 12:40:43,044 [INFO]----> ===============================================
2013-12-03 12:40:46,045 [INFO]----> Thread-6,java_lang.thread_synchronized.Sub2@15dfd77
2013-12-03 12:40:46,045 [INFO]----> Thread-7,java_lang.thread_synchronized.Sub2@15dfd77
2013-12-03 12:40:46,045 [INFO]----> Thread-5,java_lang.thread_synchronized.Sub2@15dfd77
2013-12-03 12:40:46,046 [INFO]----> Thread-8,java_lang.thread_synchronized.Sub2@15dfd77
2013-12-03 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不能被继承"的转述。(貌似很多人在这一点上存在疑惑)。

 

分享到:
评论

相关推荐

    Java关键字详细解

    `final`表示不可变,可以用于变量、方法和类,表示值不能改变、方法不能被重写、类不能被继承。 `void`表示方法无返回值,而`return`则用于从方法中返回一个值。`int`、`double`、`char`等是基本数据类型,而`...

    48个关键字

    `final`关键字用于声明常量或不可修改的对象,也可以用来防止类被继承。 ### 18. finally `finally`关键字用于异常处理,无论是否发生异常,其中的代码都会被执行。 ### 19. float `float`关键字表示单精度浮点...

    java 关键字查询文档

    Java 关键字是编程语言中具有特殊含义的保留词汇,它们不能用作变量名、类名或方法名。这些关键字在 Java 中扮演着至关重要的角色,用于定义程序结构、控制流程、内存管理等方面。这份“java 关键字查询文档”显然是...

    01-Java语言基础(关键字)

    它也可以应用于方法,表示该方法不能被子类重写,或者应用于类,表示此类不能被继承。 6. `void`: 在方法定义中,`void`表示该方法不返回任何值。 7. `int`, `float`, `double`, `char`, `boolean`: 这些是Java的...

    java关键字

    ### Java关键字详解 #### 前言 Java作为一种广泛使用的编程语言,在软件开发领域占据了重要的地位。Java的关键字,即保留字,是Java语言中具有特殊意义的...希望本文的介绍能帮助读者更好地理解和运用Java的关键字。

    深入讲解java线程与synchronized关键字

    理解并熟练运用synchronized关键字对于编写并发安全的Java代码至关重要,它可以有效地解决多线程环境下的数据同步问题,避免竞态条件和数据不一致。在实际编程中,应结合使用其他并发工具类(如Semaphore、Lock等)...

    Java关键字剖析.docx

    抽象类不能实例化,只能被继承。抽象方法没有具体实现,需要在子类中重写。 3. **类与继承**: - `class`:用于定义类,是Java中的基本构造单元,包含数据成员和方法。 - `extends`:表示类的继承关系,一个类...

    java synchronized 学习

    Java 中的 synchronized 关键字是用来实现线程同步的,它可以用来修饰方法、代码块和静态方法,以确保在多线程环境下数据的一致性。 一、进程和线程的区别 在计算机中,每个运行着的 xxxx.exe 都是一个进程,而...

    Java关键字解析.pdf

    对于类,`final`类不能被继承,确保类的封闭性和安全。 `this`关键字代表当前对象的引用,用于在方法或构造器中引用当前对象的成员变量、调用构造器或方法。例如,`this`可以用来区分局部变量和成员变量,或者在...

    Java的关键字与保留字

    18. **final**:用于声明不可变的变量或类,或指定方法不能被重写。 19. **finally**:异常处理结构的一部分,无论是否发生异常都会执行的代码块。 20. **float**:基本数据类型之一,单精度浮点数。 21. **for**:...

    Java关键字大全 Java关键字大全

    抽象类不能被实例化,而是作为其他类的基类,提供基本结构和接口。抽象方法没有具体的实现,必须在子类中被重写。如果一个类包含至少一个抽象方法,那么该类必须被声明为抽象类。 2. `boolean`:`boolean`是Java的...

    Java关键字

    在Java中,一共有51个关键字(包括保留字),但描述中提到的是48个,可能是因为某些关键字在特定上下文不常用或者被归类到保留字中。下面将详细介绍这些关键字及其用途。 1. **abstract** - 用于声明抽象类或抽象...

    java关键字总结

    在Java中,关键字是被语言保留的特定标识符,它们有特殊的含义,不能用作变量名、方法名或者类名。下面是对Java关键字的详细总结。 一、类型关键字 1. 基本数据类型:`byte`(1字节)、`short`(2字节)、`int`(4...

    JAVA关键字

    Java关键字是编程的基础,它们是Java语言预定义的、具有特殊含义的标识符,不能作为变量名、方法名或类名。以下是对50个Java关键字的详细解释: 1. **abstract**:用于声明抽象类或抽象方法,不包含具体实现。 2. ...

    java关键字、保留字

    Java关键字是由Java语言预定义的标识符,具有特殊的含义,不能用作变量名、方法名或类名等自定义标识符。本文将详细介绍Java中的关键字及其用途。 #### 关键字列表与解释 1. **abstract** - **用途**:用于声明...

    JAVA基础笔记以及关键字整理.rar

    - **synchronized**: 同步关键字,用于线程安全,确保同一时间只有一个线程执行某段代码。 - **this**: 指代当前对象的引用。 - **super**: 指代父类的引用,用于访问父类的成员。 这些关键字的理解和正确使用,...

    java关键字的使用详情

    如`final class`不能被继承,`final variable`一旦赋值就不能改变,`final method`不能被子类重写。 10. ** synchronized**: 这个关键字用于实现线程同步,确保在多线程环境中,对共享资源的访问是互斥的。 11. **...

    java语言关键字.pdf

    * abstract:用在类的声明中,指明一个类是不能被实例化的,但是可以被其它类继承。 * class:用来定义一个类,它包含有关对象的信息,包括名称、方法、属性和事件。 * extends:用来继承一个类,添加功能,或者添加...

    JAVA中的保留关键字

    - `final`:表示常量、最终类或方法不能被覆盖。 - `finally`:无论是否发生异常都会执行的代码块。 - `float`:表示单精度浮点数类型。 - `for`:启动一个for循环。 - `if`:根据条件选择执行不同的代码路径。 - `...

Global site tag (gtag.js) - Google Analytics