1、synchronized的使用
Synchronized主要有三种用法:
(1)修饰实例方法: 作用于当前对象实例加锁,进入同步代码前要获得当前对象实例的锁。
synchronized void method() {
//业务代码
}
(2)修饰静态方法: 也就是给当前类加锁,会作用于类的所有对象实例 ,进入同步代码前要获得当前 class 的锁。因为静态成员不属于任何一个实例对象,是类成员( static 表明这是该类的一个静态资源,不管 new 了多少个对象,只有一份)。所以,如果一个线程 A 调用一个实例对象的非静态 synchronized 方法,而线程 B 需要调用这个实例对象所属类的静态 synchronized 方法,是允许的,不会发生互斥现象,因为访问静态 synchronized 方法占用的锁是当前类的锁,而访问非静态 synchronized 方法占用的锁是当前实例对象锁。
synchronized void staic method() {
//业务代码
}
(3)修饰代码块 :指定加锁对象,对给定对象/类加锁。synchronized(this|object) 表示进入同步代码库前要获得给定对象的锁。synchronized(类.class) 表示进入同步代码前要获得 当前 class 的锁。
synchronized(this) {
//业务代码
}
更多内容可见博客:
synchronized详解_三分恶的博客-CSDN博客_synchronized
2、多态:向上转型和向下转型
向上转型:
(1)对象的类型为父类类型,对象的属性使用的是父类的属性。
(2)方法使用的是子类和父类共有的方法,其中,若子类有重写父类的方法则使用重写后的方法。
向下转型:
(1)语法:子类类型 引用名 = (子类类型) 父类引用。
(2)只能强转父类的引用,不能强转父类的对象。
(3)要求父类的引用必须指向的是当前目标类型的对象。
(4)向下转型后,可以调用子类类型中的所有成员。
各类易错情况的代码举例:
interface Foo{
}
class Alpha implements Foo {
}
class Beta extends Alpha{
}
public class Demo1 extends Beta{
public static void main(String[] args) {
//多态,父类引用指向子类对象
Beta x=new Beta();
Alpha a=x;
Foo f1=new Alpha();
Foo f2=new Beta();
Foo f3=new Demo1();
// 父类对象不能强转
// Foo f4=(demo1)x;
//具有继承关系的父子类,在父类引用指向子类对象后,该引用可以向下造型。
Beta x1=new Demo1();
Foo f5=(Demo1)x1;
Alpha x2=new Demo1();
Foo f6=(Demo1)x2;
//父类的引用必须指向的是当前目标类型的对象
Alpha x3=new Beta();
Foo f7=(Demo1)x3;
}
}
更多内容可见博客:
JAVA向下转型的错误示例和正确示例_我的Y同学的博客-CSDN博客_java 向下转型报错
3、锁的释放
(1)sleep()不会释放锁。
(2)wait()会释放锁。
(3)notify()不会释放锁。