网上看到很多对关键字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不能被继承"的转述。(貌似很多人在这一点上存在疑惑)。
相关推荐
`final`表示不可变,可以用于变量、方法和类,表示值不能改变、方法不能被重写、类不能被继承。 `void`表示方法无返回值,而`return`则用于从方法中返回一个值。`int`、`double`、`char`等是基本数据类型,而`...
`final`关键字用于声明常量或不可修改的对象,也可以用来防止类被继承。 ### 18. finally `finally`关键字用于异常处理,无论是否发生异常,其中的代码都会被执行。 ### 19. float `float`关键字表示单精度浮点...
Java 关键字是编程语言中具有特殊含义的保留词汇,它们不能用作变量名、类名或方法名。这些关键字在 Java 中扮演着至关重要的角色,用于定义程序结构、控制流程、内存管理等方面。这份“java 关键字查询文档”显然是...
它也可以应用于方法,表示该方法不能被子类重写,或者应用于类,表示此类不能被继承。 6. `void`: 在方法定义中,`void`表示该方法不返回任何值。 7. `int`, `float`, `double`, `char`, `boolean`: 这些是Java的...
### Java关键字详解 #### 前言 Java作为一种广泛使用的编程语言,在软件开发领域占据了重要的地位。Java的关键字,即保留字,是Java语言中具有特殊意义的...希望本文的介绍能帮助读者更好地理解和运用Java的关键字。
理解并熟练运用synchronized关键字对于编写并发安全的Java代码至关重要,它可以有效地解决多线程环境下的数据同步问题,避免竞态条件和数据不一致。在实际编程中,应结合使用其他并发工具类(如Semaphore、Lock等)...
抽象类不能实例化,只能被继承。抽象方法没有具体实现,需要在子类中重写。 3. **类与继承**: - `class`:用于定义类,是Java中的基本构造单元,包含数据成员和方法。 - `extends`:表示类的继承关系,一个类...
Java 中的 synchronized 关键字是用来实现线程同步的,它可以用来修饰方法、代码块和静态方法,以确保在多线程环境下数据的一致性。 一、进程和线程的区别 在计算机中,每个运行着的 xxxx.exe 都是一个进程,而...
对于类,`final`类不能被继承,确保类的封闭性和安全。 `this`关键字代表当前对象的引用,用于在方法或构造器中引用当前对象的成员变量、调用构造器或方法。例如,`this`可以用来区分局部变量和成员变量,或者在...
18. **final**:用于声明不可变的变量或类,或指定方法不能被重写。 19. **finally**:异常处理结构的一部分,无论是否发生异常都会执行的代码块。 20. **float**:基本数据类型之一,单精度浮点数。 21. **for**:...
在Java中,一共有51个关键字(包括保留字),但描述中提到的是48个,可能是因为某些关键字在特定上下文不常用或者被归类到保留字中。下面将详细介绍这些关键字及其用途。 1. **abstract** - 用于声明抽象类或抽象...
在Java中,关键字是被语言保留的特定标识符,它们有特殊的含义,不能用作变量名、方法名或者类名。下面是对Java关键字的详细总结。 一、类型关键字 1. 基本数据类型:`byte`(1字节)、`short`(2字节)、`int`(4...
Java关键字是编程的基础,它们是Java语言预定义的、具有特殊含义的标识符,不能作为变量名、方法名或类名。以下是对50个Java关键字的详细解释: 1. **abstract**:用于声明抽象类或抽象方法,不包含具体实现。 2. ...
Java关键字是由Java语言预定义的标识符,具有特殊的含义,不能用作变量名、方法名或类名等自定义标识符。本文将详细介绍Java中的关键字及其用途。 #### 关键字列表与解释 1. **abstract** - **用途**:用于声明...
- **synchronized**: 同步关键字,用于线程安全,确保同一时间只有一个线程执行某段代码。 - **this**: 指代当前对象的引用。 - **super**: 指代父类的引用,用于访问父类的成员。 这些关键字的理解和正确使用,...
如`final class`不能被继承,`final variable`一旦赋值就不能改变,`final method`不能被子类重写。 10. ** synchronized**: 这个关键字用于实现线程同步,确保在多线程环境中,对共享资源的访问是互斥的。 11. **...
对于类,不能被继承;对于方法,不能被子类重写。 11. **finally**:确保一段代码无论是否发生异常都会被执行,通常用于清理资源,如关闭文件或网络连接。 12. **float**:声明单精度浮点型变量,比double精度低,...
* abstract:用在类的声明中,指明一个类是不能被实例化的,但是可以被其它类继承。 * class:用来定义一个类,它包含有关对象的信息,包括名称、方法、属性和事件。 * extends:用来继承一个类,添加功能,或者添加...
- `final`:表示常量、最终类或方法不能被覆盖。 - `finally`:无论是否发生异常都会执行的代码块。 - `float`:表示单精度浮点数类型。 - `for`:启动一个for循环。 - `if`:根据条件选择执行不同的代码路径。 - `...
修饰符如`private`, `public`, `protected`定义了访问权限,`final`, `static`, `abstract`, `native`, `synchronized`, `volatile`, `strictfp`, `transient`分别用于定义不可变对象、静态成员、抽象方法、本地方法...