Java_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Java

Java

 2013/12/3 15:26:11  琼海溜  程序员俱乐部  我要评论(0)
  • 摘要:网上看到很多对关键字synchronized继承性的描述只有一句"关键字synchronized不能被继承",并没有描述具体场景,于是自己做了以下测试。//父类publicclassSuper{staticLoggerlogger=Logger.getLogger(Super.class);//同步方法@SuppressWarnings("static-access")publicsynchronizedvoidtestMothed(){try{Thread.currentThread()
  • 标签: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不能被继承"的转述。(貌似很多人在这一点上存在疑惑)。

?

发表评论
用户名: 匿名