多线程进阶之并发工具类: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 工具类则提供了在线 ...
随机推荐
- 前台javascript排序
<script type="text/javascript"> $(function () { $('.Sorthead-ShowUp').click(function ...
- openwrt 更改 debug 等级(hostapd)
https://wiki.openwrt.org/doc/devel/debugging 调试hostapd,其中hostapd的调试等级如下: # Levels (minimum value for ...
- Redis4- llist的操作
数据类型List链表(1)介绍list类型其实就是一个双向链表.通过push,pop操作从链表的头部或者尾部添加删除元素.这使得list既可以用作栈,也可以用作队列.该list链表类型应用场景:获得最 ...
- HDU - 1045 Fire Net(二分匹配)
Description Suppose that we have a square city with straight streets. A map of a city is a square bo ...
- memcached + php 扩展 for ubuntu
1.安装memcached apt-get install memcached 2.安装php memcached 扩展 apt-get install php5-memcache 3.启动memca ...
- js cookie 记住用户名密码
function saveUserInfo(){ if($("#remember").attr('checked')=="checked"){ var user ...
- Jena文档《An Introduction to RDF and the Jena RDF API》的译文
前言本文是一篇对W3C的资源描述框架(RDF)和 Jena(一个Java的RDF API)的教程性介绍. 本文是为那些不熟悉RDF的, 以及那些通过建立原形可以达到最好学习效果的, 或是因为其他原因希 ...
- js 插入图片切换,innerHTML
<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content=&q ...
- CSS3秘笈:第七章
第七章 margin.padding和border 1.盒模型:四个属性: (1)padding:内容与其边框线之间的空间. (2)border:盒子周围的直线 (3)background-colo ...
- hibernate对象的状态以及生命周期
瞬时状态:session中没有,数据库中没有 持久状态:session中有,数据库中有 游离状态:session中没有,数据库中有 get和load都是用来提取数据的 get和load的区别: get ...