synchronized关键字不能被继承的问题

sandybeach88 2012-03-30 12:42:22
我发现许多地方提及synchronized的关键字不能被继承,但是通过实验发现synchronized的关键字是能够被继承的,是我的实验方式不对?请高手指教,谢谢

import java.text.SimpleDateFormat;
import java.util.Date;

public class TestMain {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
UtilChild util = new UtilChild();

AThread aThread1 = new AThread(util,1);
aThread1.start();
AThread aThread2 = new AThread(util,2);
aThread2.start();
AThread aThread3 = new AThread(util,3);
aThread3.start();
AThread aThread4 = new AThread(util,4);
aThread4.start();
AThread aThread5 = new AThread(util,5);
aThread5.start();

}

}

class Util{

public static synchronized void test1(int i){
System.out.println(getDetailDate() + " test1(i), i: " + i);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(getDetailDate() + " test1(i), i: " + i);
}

public static synchronized void test2(int i){
System.out.println(getDetailDate() + " test2(i), i: " + i);
}

public static void test3(int i){
System.out.println(getDetailDate() + " test3(i), i: " + i);
}

public synchronized void test4(int i){
System.out.println(getDetailDate() + " test4(i), i: " + i);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(getDetailDate() + " test4(i), i: " + i);
}

public synchronized void test5(int i){
System.out.println(getDetailDate() + " test5(i), i: " + i);
}

public static String getDetailDate() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(new Date());
}
}

class UtilChild extends Util{

}

class AThread extends Thread{
UtilChild util = null;
int i = 1;
public AThread(UtilChild util, int i){
this.util = util;
this.i = i;
}

public void run(){
if(this.i== 1){
util.test1(1);
}else if(this.i== 2){
util.test2(2);
}else if(this.i== 3){
util.test3(i);
}else if(this.i== 4){
util.test4(i);
}else if(this.i== 5){
util.test5(i);
}

}
}

运行结果:


2012-03-30 00:40:02 test4(i), i: 4
2012-03-30 00:40:02 test3(i), i: 3
2012-03-30 00:40:02 test1(i), i: 1
2012-03-30 00:40:07 test4(i), i: 4
2012-03-30 00:40:07 test5(i), i: 5

2012-03-30 00:40:07 test1(i), i: 1
2012-03-30 00:40:07 test2(i), i: 2
...全文
696 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
gaofuqi 2014-08-07
  • 打赏
  • 举报
回复
如果不能被继承,在AThread 类编译时就会报错,UtilChild除了test3方法就没有其他方法了。
gaofuqi 2014-08-07
  • 打赏
  • 举报
回复
synchronized不能被继承,这是哪看到的资料,我怎么从未看到过?
  • 打赏
  • 举报
回复
引用 11 楼 smallsmallc 的回复:
其实真相是这样的,“synchronized不能被继承”,这句话有2种不同意思,一种是比较正常的、很容易让人想到的意思;另一种是“不正常的”或者说是“java中文界”广泛认同了的意思。 楼主是第一种意思,其他人是第二种意思。所以,会出现该贴的尴尬讨论。 第一种理解方式:父类中有个synchronized方法,子类继承了父类,但子类没覆写该方法。通过子类实例来使用该方法时,按“synchronized不能被继承”,意思就为:该子类的该方法就变成了非synchronized方法。 第二种理解方式:synchronized并不属于方法定义的一部分,不能被继承。子类覆写了该方法,如果在覆写时不明确写上synchronized,那这个方法就不是synchronized。换句话说,虽然继承了,但是没把synchronized继承下来,也就意味着“synchronized不能被继承”。 我觉得“synchronized不能被继承”这句话,没把意思表述清楚。产生这种情况的原因,我推测是这样的:某前辈详细解释了以上2种意思,最后总结的时候,使用了“synchronized不能被继承”这句不太合适的话。某无知后辈转述前辈意思的时候,就直接用了“synchronized不能被继承”。结果一传十,十传百,这句话就传开了,也让初学者产生了迷惑。 在英文世界里,没有“synchronized不能被继承”的讨论。这也说明了点问题。 其实楼主的问题,可以记住这么句话:synchronized方法,一定要显示标明,它是不能隐式标明的。 中文里“一句话多种意思”的问题,真的是给学术界增加了不少麻烦!
直接说就是不重写的话 子类使用时是也是按同步的来用的;重写的话,要显示声明synchronized才是同步。对不?
smallsmallc 2013-03-16
  • 打赏
  • 举报
回复
引用 13 楼 beyondziming 的回复:
刚刚我没运行 运行后发现结果继承同步方法了。 我跟楼主一样的方法了 汗。
“结果继承同步方法了”,同志,别这样,这句话和“synchronized不能被继承”一样,会产生歧义,误导别人的!
smallsmallc 2013-03-16
  • 打赏
  • 举报
回复
引用 11 楼 smallsmallc 的回复:
其实真相是这样的,“synchronized不能被继承”,这句话有2种不同意思,一种是比较正常的、很容易让人想到的意思;另一种是“不正常的”或者说是“java中文界”广泛认同了的意思。 楼主是第一种意思,其他人是第二种意思。所以,会出现该贴的尴尬讨论。 第一种理解方式:父类中有个synchronized方法,子类继承了父类,但子类没覆写该方法。通过子类实例来使用该方法……
没说明白,再补充下下:子类不覆写该方法时,通过子类实例调用该方法,其实使用的还是父类的方法,因此该方法仍然是synchronized。所以楼主的输出,当然是synchronized的效果。
smallsmallc 2013-03-16
  • 打赏
  • 举报
回复
以此贴为依托!!发一个倡导! 本人混迹CSDN有几年了,只看帖不回帖,shame for me!但是发现CSDN中水问题的人太多了!! 一是不理解楼主问题,二是自己也一知半解,就跑出来回答别人问题!这不误导别人么。 CSDN中真大神有很多,可是太潜水了,只看帖、只嘲笑!不回帖呀!!!应该是不屑、怕回答错、或者不愿花时间。只要认真回答问题了,即使回答错了,没人会嘲笑的!!! CSDN的一直在走下坡路啊,看看当年的前辈是如何帮人解惑的,后辈们羞愧否!!!! 呼唤CSDN真大神出现!别再潜水了!!!
凌云紫冥 2013-03-16
  • 打赏
  • 举报
回复
刚刚我没运行 运行后发现结果继承同步方法了。 我跟楼主一样的方法了 汗。
smallsmallc 2013-03-16
  • 打赏
  • 举报
回复
引用 10 楼 beyondziming 的回复:
首先,synchronized不被继承,所以你不加这个关键字 输出结果应该也是一样的。 那么一个线程执行了test4后,另外一个线程应该可以立刻执行test5, 这是对的,没有同步另外一个线程是可以立即执行test5的, 但是由于楼主你程序的输出结果这个速度很快 cpu处理非常快 所以你没有同步 它一瞬间就把结果输出 2012-03-30 00:40:07 tes……
Shame for you!!
smallsmallc 2013-03-16
  • 打赏
  • 举报
回复
其实真相是这样的,“synchronized不能被继承”,这句话有2种不同意思,一种是比较正常的、很容易让人想到的意思;另一种是“不正常的”或者说是“java中文界”广泛认同了的意思。 楼主是第一种意思,其他人是第二种意思。所以,会出现该贴的尴尬讨论。 第一种理解方式:父类中有个synchronized方法,子类继承了父类,但子类没覆写该方法。通过子类实例来使用该方法时,按“synchronized不能被继承”,意思就为:该子类的该方法就变成了非synchronized方法。 第二种理解方式:synchronized并不属于方法定义的一部分,不能被继承。子类覆写了该方法,如果在覆写时不明确写上synchronized,那这个方法就不是synchronized。换句话说,虽然继承了,但是没把synchronized继承下来,也就意味着“synchronized不能被继承”。 我觉得“synchronized不能被继承”这句话,没把意思表述清楚。产生这种情况的原因,我推测是这样的:某前辈详细解释了以上2种意思,最后总结的时候,使用了“synchronized不能被继承”这句不太合适的话。某无知后辈转述前辈意思的时候,就直接用了“synchronized不能被继承”。结果一传十,十传百,这句话就传开了,也让初学者产生了迷惑。 在英文世界里,没有“synchronized不能被继承”的讨论。这也说明了点问题。 其实楼主的问题,可以记住这么句话:synchronized方法,一定要显示标明,它是不能隐式标明的。 中文里“一句话多种意思”的问题,真的是给学术界增加了不少麻烦!
凌云紫冥 2013-03-16
  • 打赏
  • 举报
回复
首先,synchronized不被继承,所以你不加这个关键字 输出结果应该也是一样的。 那么一个线程执行了test4后,另外一个线程应该可以立刻执行test5, 这是对的,没有同步另外一个线程是可以立即执行test5的, 但是由于楼主你程序的输出结果这个速度很快 cpu处理非常快 所以你没有同步 它一瞬间就把结果输出 2012-03-30 00:40:07 test4(i), i: 4 2012-03-30 00:40:07 test5(i), i: 5 这样的输出结果说明 线程执行4.。。。在运行。。。啪。。 一下输出结果了。。。继续运行后面代码 线程执行5。。。。也在运行。。。啪。。一下也出结果了 没同步的话其实是一起运行的 只是输出结果造成你的困扰吧。
小C 2013-03-16
  • 打赏
  • 举报
回复
不能忍啊!!!!!!!!!!看不下去了!!!!!!!!!!!!!!! 楼上居然没一个人懂楼主的问题! 深刻同情楼主!
破布_ 2013-03-16
  • 打赏
  • 举报
回复
子类和父类属于两个类,如果子类重写了父类,方法表指向的是子类的,如果没有重写,方法表指向的是父类的。
破布_ 2013-03-16
  • 打赏
  • 举报
回复
子类和父类...
logic_well 2012-04-08
  • 打赏
  • 举报
回复
输出结果有什么问题吗?两个4之间有1出现 两个1之间也有4和5出现 说明test1和test4 test5未发生互斥 也就说明synchronized未被继承
你所说的Test4和Test5要锁同一对象怎么会没有互斥关系
多线程的过程不是按顺序往下走 它们并行在准备区里等CPU抽空来处理
执行完4后是否立即执行5是CPU说了算 不是你说了算 也不是synchronized说了算 还有你看到5在4后边执行 为什么看不到在4的执行期间还执行了3和1?
synchronized能保证的是加synchronized的所有方法在调用同一对象时只有一个方法在对其进行操作
sandybeach88 2012-04-02
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

这程序说明啥问题啊?test1和test4至少要隔5000ms才执行一次,test2,3,5,得到系统资源就可以执行
[/Quote]

这个程序是多线程执行
2012-03-30 00:40:02 test4(i), i: 4
2012-03-30 00:40:02 test3(i), i: 3
2012-03-30 00:40:02 test1(i), i: 1
2012-03-30 00:40:07 test4(i), i: 4
2012-03-30 00:40:07 test5(i), i: 5
2012-03-30 00:40:07 test1(i), i: 1
2012-03-30 00:40:07 test2(i), i: 2
加睡眠只是为了防止程序执行的太快,看不出效果。
test4和test5之间同步锁是UtilChild这个类的对象,是没有互斥关系的,如果synchronized是不被继承的话,那么test4和test5的方法在UtilChild类中是不是应该理解为:
public void test4(int i){
.....
}
public void test5(int i){
.....
}
没有synchronized修饰符的?
那么一个线程执行了test4后,另外一个线程应该可以立刻执行test5,不需要等待test4方法完全执行完之后再执行test5。
同理test1和test2之间同步锁对象是UtilChild这个类本身,为什么要等test1完全执行完之后才执行test2?
kakashi8841 2012-04-01
  • 打赏
  • 举报
回复
synchronized本来就不能继承……
tanrenzong1986 2012-03-31
  • 打赏
  • 举报
回复
synchronized不能继承的。
爱摸鱼de老邪 2012-03-31
  • 打赏
  • 举报
回复
真没看出来楼主你这哪里继承synchronized的关键字,只看出多态。
zhou074 2012-03-31
  • 打赏
  • 举报
回复
这程序说明啥问题啊?test1和test4至少要隔5000ms才执行一次,test2,3,5,得到系统资源就可以执行
酒比花香 2012-03-30
  • 打赏
  • 举报
回复
路过。。。从学java开始线程就没懂过。。。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧