多线程进阶之并发工具类:CountDownLatch、CyclicBarrier
在Java中,类不能多继承。啥意思呢?就是说一个类不能既继承A,又继承B,它只能继承一个类,否则在编译时会报错 Class cannot extend multiple classes。
子类继承父类时,会继承父类的成员变量和方法,但是不是所有的成员变量和方法都会继承,这里也常常是笔试题考点。
会继承哪些成员变量呢?
首先这个成员变量必须是非静态的,其次再看访问修饰符,public、protected的会继承,缺省的包访问修饰符修饰的话,子类如果和父类在同一个包下,也会继承。其他都不继承。
如果在子类中没有定义同名的非静态变量,则在子类中可以用this.变量名或者super.变量名获取变量的值,this可以省略。如果在子类中重新定义了同名的非静态变量,则在子类中想获取父类的变量值只能用super.变量名,想获取子类的变量值可以用this.变量名,this也可以省略。注意,子类重新定义同名非静态变量时,变量类型可以为任意类型。
另外一种情况,如果把子类实例赋值给父类变量,则父类变量的成员变量值是父类定义的那个,还是子类定义的那个?如下示例:
public static void main(String[] args) {
MySuper m = new MySub();
System.out.println(m.a);
System.out.println(m.b);
} static class MySub extends MySuper {
private boolean a = true;
private boolean d = true;
} static class MySuper {
public int a = 0;
protected int b = 1;
public static int d = 3;
}
直接打点获取变量值,是看编译类型的,不看运行时类型。这是和方法调用很大区别的一个地方。
上面会打印
0
1
会继承哪些方法呢?
首先,构造器不会继承,静态方法不会继承,其次再看访问修饰符,public、protected的会继承,缺省的包访问修饰符修饰的话,子类如果和父类在同一个包下,也会继承。其他都不继承。
继承来的方法我们要是自定义实现的话,这就是所谓的重写了。
非静态方法的调用是看调用者的运行时类型的,如果是静态方法的话,则看调用者的编译时类型,因为静态方法不会被继承。
如下示例:
public static void main(String[] args) {
MySuper m = new MySub();
m.hh();
m.sp();
} static class MySub extends MySuper {
public MySub() {
} @Override
public void hh() {
System.out.println("sub" + 1);
} public static void sp() {
System.out.println(1);
} } static class MySuper { public MySuper() {
} public void hh() {
System.out.println(1);
} public static void sp() {
System.out.println(2);
}
}
以上,hh()是非静态方法,且是public的,MySub可从MySuper继承。MySub又重写了hh()方法。在调用时看调用者的运行时类型,发现其实是MySub类型,就会去执行MySub的hh()方法。
sp()是静态方法,不可被继承。在调用时,看调用者的编译时类型,发现是MySuper类型,就执行MySuper的sp()方法。
下面再讲一下构造器。
构造器是不可被继承的,构造器是不可被继承的,构造器是不可被继承的。重要的事情说三遍。
调用子类构造器时,会先调用父类构造器。什么意思呢?调用父类的哪个构造器呢?
如果子类构造器的实现代码中,第一行用super(参数列表)指定了父类的构造器,则会先调用这个指定的构造器,然后再执行子类构造器中后面的代码。如果没有在第一行用super显式指定构造器,则会调用父类的无参构造器,之后再执行子类构造器中的代码。
public static void main(String[] args) {
MySuper m1 = new MySub();
MySuper m2 = new MySub(2);
} static class MySub extends MySuper { public MySub() {
System.out.println("MySub 无参");
} public MySub(int a) {
super(a);
System.out.println("MySub 有参");
} } static class MySuper { public MySuper() {
System.out.println("MySuper 无参");
} public MySuper(int a) {
System.out.println("MySuper 有参, 参数值是= " + a);
}
}
再多说一点,类的静态成员变量初始化、静态代码块都是在类加载时执行的,且只会执行一次。类只有在用到的时候才会加载。如果有父类,则会先初始化父类的静态成员变量、执行静态代码块,再初始化子类的静态成员变量、执行静态代码块。注意,这时候,子类、父类的非静态成员变量还没有初始化、非静态代码块还没有执行。类的静态成员变量初始化和静态代码块的执行顺序与代码中的顺序一样。
调用子类的构造器时,会先初始化父类的非静态成员变量、执行父类的非静态代码块,再执行父类的构造器,之后才开始初始化子类的非静态成员变量、执行子类的非静态代码块,最后再执行子类的构造器。类的非静态成员变量初始化和非静态代码块的执行顺序与代码中的顺序一样。
面试的时候碰见过一种极端情况,就是在父类的构造器中调用一个非静态方法,打印一个成员变量的值,这个非静态方法又被子类重写了。子类覆盖了父类的这个成员变量。看打印出什么。
public class Test {
public static void main(String[] args) {
Base obj = new Sub();
System.out.println(obj.x);
System.out.println(obj.getX());
} public static class Base {
int x = 1; public Base() {
this.echo();
this.x = 2;
} public void echo() {
System.out.println("Base.x=" + this.x);
} public int getX() {
return this.x;
}
} public static class Sub extends Base {
int x = 3; public Sub() {this.x = 4;
this.echo();
this.x = 4;
} @Override
public void echo() {
System.out.println("Sub.x=" + this.x);
} @Override
public int getX() {
return this.x;
}
}
}
案例解析:
执行new Sub(),由于第一行不是用super来显式调用父类构造器,所以是隐式地调用父类的无参构造器。Base的无参构造器中调用了this.echo()方法,这个方法又被Sub重写了,所以最终调用的是Sub的echo()方法。
多线程进阶之并发工具类:CountDownLatch、CyclicBarrier的更多相关文章
- Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger
在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...
- java多线程10:并发工具类CountDownLatch、CyclicBarrier和Semaphore
在JDK的并发包(java.util.concurrent下)中给开发者提供了几个非常有用的并发工具类,让用户不需要再去关心如何在并发场景下写出同时兼顾线程安全性与高效率的代码. 本文分别介绍Coun ...
- java 并发工具类CountDownLatch & CyclicBarrier
一起在java1.5被引入的并发工具类还有CountDownLatch.CyclicBarrier.Semaphore.ConcurrentHashMap和BlockingQueue,它们都存在于ja ...
- Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo
Java并发编程工具类 CountDownLatch CyclicBarrier Semaphore使用Demo CountDownLatch countDownLatch这个类使一个线程等待其他线程 ...
- 30行自己写并发工具类(Semaphore, CyclicBarrier, CountDownLatch)是什么体验?
30行自己写并发工具类(Semaphore, CyclicBarrier, CountDownLatch)是什么体验? 前言 在本篇文章当中首先给大家介绍三个工具Semaphore, CyclicBa ...
- Java并发工具类 - CountDownLatch
Java并发工具类 - CountDownLatch 1.简介 CountDownLatch是Java1.5之后引入的Java并发工具类,放在java.util.concurrent包下面 http: ...
- Java并发工具类CountDownLatch源码中的例子
Java并发工具类CountDownLatch源码中的例子 实例一 原文描述 /** * <p><b>Sample usage:</b> Here is a pai ...
- 多线程学习笔记六之并发工具类CountDownLatch和CyclicBarrier
目录 简介 CountDownLatch 示例 实现分析 CountDownLatch与Thread.join() CyclicBarrier 实现分析 CountDownLatch和CyclicBa ...
- Java中的并发工具类(CountDownLatch、CyclicBarrier、Semaphore、Exchanger)
在JDK的并发包里提供了很多有意思的并发工具类.CountDownLatch.CyclicBarrier和Semaphore 工具类提供了一种并发流程控制的手段,Exchanger 工具类则提供了在线 ...
随机推荐
- 浙大pat1042题解
1042. Shuffling Machine (20) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Shu ...
- #if defined和#if !defined(c语言的宏定义)
我们要检查a是否定义 #if defined a #undef a #define a 200 #endif 上述语句检验a是否被定义,如果被定义,则用#undef语句解除定义,并重新定义a为200 ...
- 记2016商大ACM省赛
比赛前三天才得到省赛的非正式参赛名额,总有点哭笑不得,笑的是是我的终究是我的,跑不掉…… 哭的是现在就剩三天了,虽然最近也一直在参加训练赛,但一直是断断续续的,对自己现在的水平并没有太大的信心…… 虽 ...
- C#中使用ServiceStack.Redis
.Net操作Redis数据类型String public class DoRedisString : DoRedisBase { #region 赋值 /// <summary> /// ...
- Xcode中AutoLayOut的简单使用
做了一段界面最头疼的就是适配的问题了,使用AutoLayOut做适配是一个不错的选择, 自己做的一个小例子,具体如下: 一.在新建的xib文件中勾选上 autoLayout,默认是勾选上的 二.在xi ...
- ThinkPHP框架基础
ThinkPHP 一.php框架基础介绍 真实项目开发步骤: 多人同时开发项目,协作开发项目.分工合理.效率有提高(代码风格不一样.分工不好) 测试阶段 上线运行 对项目进行维护.修改.升级(单个人维 ...
- 2.定义图形类Shape,该类中有获得面积的方法getArea();定义长方形类Rect,该类是Shape的子类,类中有矩形长和宽的变量double a,double b,设置长和宽的方法setWidth()、setHeight(),使用getArea()求矩形面积;利用getArea方法实现题1中圆面积的求解。
// 图形类Shape package d922B; public class Shape { double getArea(ShapePara x){ return x.getArea(); } d ...
- Linux openvswitch性能调优
Increasing the flow-eviction threshold The threshold is a type of limit on the number of flows that ...
- php根据IP获取IP所在城市
转载出处:php实现根据IP地址获取其所在省市的方法 //根据现有IP地址获取其地理位置(省份,城市等)的方法 function GetIpLookup($ip = ''){ if(empty($ip ...
- selinux策略开发
所用软件: 1.setools -->seaudit 读取日志以确定所需权限 2.Reference Policy --> https://github.com/TresysTech ...