多线程进阶之并发工具类: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 工具类则提供了在线 ...
随机推荐
- 设置div控件居中的方法
margin是设置外边距的,它有四个值,margin:4px 5px 5px 5px;分别表示上边距,右边距,下边距,和左边距,是从上按顺时针设置的,如果单个设置,他又有margin-top:3px: ...
- 1、第一个SpringMVC程序
1.创建如下项目结构 2.在src下的com.springmvc下创建User.java package com.springmvc; public class User { private Stri ...
- 触动精灵远程Log模块
一.功能 lua log方法能够自动发现同一网段下面的log服务器 lua log方法能够主动将log发给服务器 lua 客户端进程重启服务端不存在影响 二.实现 服务器使用python编写: 启动一 ...
- NSCondition
一.NSCondition是对条件变量和互斥量的一个封装,用于线程之间的同步. 其中的互斥量用于保护对条件变量的修改,条件变量变化以信号量的方式通知其它线程实现线程之间的同步. 二.NSConditi ...
- java增加时间
一个简单的东西. 示例如下: /** * 增加时间 * @param oldDate 老时间 * @param addtime 增加的时间 * @return */ public Date addDa ...
- spring容器启动的加载过程(一)
使用spring,我们在web.xml都会配置ContextLoaderListener <listener> <listener-class> org.springframe ...
- zend guard Optimizer
zend guard Optimizer PHP5.3+ URL:http://www.zend.com/en/products/guard/downloads Email:test001@test0 ...
- Nginx负载均衡反向代理 后端Nginx获取客户端真实IP
Nginx 反向代理后,后端Nginx服务器无法正常获取客户端的真实IP nginx通过http_realip_module模块来实现的这需要重新编译,如果提前编译好了就无需重新编译了1,重新编译ng ...
- python多线程,多进程
线程是公用内存,进程内存相互独立 python多线程只能是一个cpu,java可以将多个线程平均分配到其他cpu上 以核为单位,所以GIL(全局锁,保证线程安全,数据被安全读取)最小只能控制一个核,很 ...
- Webdriver的设计模式:Page Object(页面模型)
设计思想:面向对象,将单个页面所有可能用到元素封装到一个page类中,并提供一些常用的方法,其属性就代表页面元素,普通方法代表对元素所做的操作 以博客园的登录页面为例: import org.open ...