面向对象-多线程-异常机制-查漏补缺

查漏补缺
[1].this语句;
this语句用于构造函数之间进行相互调用。
this语句只能定义在构造函数的第一行,因为初始化要先执行。
[2].对象的初始化过程
Person p =new Person("hei",10);
1.因为new用到了Person.class,所以先找到Person.class文件加载到内存中
2.执行类中的静态代码块,如果有的话,给Person.class类进行初始化
3.在堆内存中开辟空间,分配内存地址
4.在堆内存中建立对象的特有属性,并进行默认初始化
5.对属性进行显式初始化
6.对对象进行构造代码块初始化
7.对对象进行与之对应的构造初始化
8.将内存地址赋值给内存中的p变量
[3].对象的执行过程
静态方法调用是 类名.静态方法()
静态属性调动是 类名.属性
注:类名一般省略
非静态的方法调用是 this.方法()
非静态的属性调用是 this.属性

[4]单例
1.将构造函数私有化
2.在类中提供一个本类对象
3.对外提供一个获取本类对象的方法

[5]继承对象的初始化执行过程

package cn.soldier.oop;

class Fu {
public static int fuNum = 23;
int num = 10;
static {
System.out.println("static Fu.enclosing_method()... fuNum=" + fuNum);
}

{
System.out.println("Fu.enclosing_method().... fuNum=" + ++fuNum + " num=" + ++num);
}

// Fu() {
// num = 20;
// System.out.println("Fu.Fu() num=" + ++num);
// }

Fu(int i) {

System.out.println("Fu.Fu(int) i=" + ++i);
}

private static void show() {

System.out.println("Fu.show() fuNum=" + fuNum);
}
}

class Zi extends Fu {
public static int ziNum = 23;

static {
System.out.println("static Zi.enclosing_method()... zinum= " + ziNum);
}

{
System.out.println("Zi.enclosing_method()... zinum=" + ++ziNum + " num=" + ++num);
}

// Zi() {
// System.out.println("Zi.Zi()");
// }

Zi(String zi, int i) {
// this()
super(i);
System.out.println("Zi.Zi((String zi zi=) .... " + zi+" .... i=" + ++i);
}
}

public class hello {

public static void main(String[] args) {
// 测试zi开辟空间先还是Fu开辟空间先
int i = 0;
Zi zi = new Zi("hello", i);
}
}
//下面是打印结果
//static Fu.enclosing_method()... fuNum=23
//static Zi.enclosing_method()... zinum= 23
//Fu.enclosing_method().... fuNum=24 num=11
//Fu.Fu(int) i=1
//Zi.enclosing_method()... zinum=24 num=12
//Zi.Zi((String zi zi=) .... hello .... i=1
1.程序启动找到main方法

2.先将main方法中的i放入栈中,并为其初始化。

3.然后执行到 Zi zi = new Zi("hello", i);

  1.先将局部变量 zi放入栈中
  2.将Zi.class文件加载进内存,发现Zi类继承了Fu类,又将Fu.class加载进内存。
  3.将Fu类的静态成员、静态方法、静态代码块放入方法区静态区域。
  4.将Fu类的静态成员默认初始化,如果静态成员有被赋值的话,那么将赋值的静态成员显示初始化。
  5.执行Fu类的静态代码块。所以打印的第一行是:static Fu.enclosing_method()... fuNum=23
  6.将Zi类的静态成员、静态方法、静态代码块放入方法区静态区域。
  7.将Zi类的静态成员默认初始化,如果静态成员有被赋值的话,那么将赋值的静态成员显示初始化。
  8.执行Zi类的静态代码块。所以打印的第二行是:static Zi.enclosing_method()... zinum= 23
  9.在堆内存中开辟空间,为Fu类分配内存地址.
  10.在堆内存中建立Fu对象的成员,并进行默认初始化,如果成员有被赋值的话,那么将赋值的成员显示初始化。
  11.将Fu类的方法放入方法区
  12.执行Fu类的构造代码块,所以打印的第三行是:Fu.enclosing_method().... fuNum=24 num=11
  13.执行Fu类的构造方法,Fu(int)所以打印的第四行是:Fu.Fu(int) i=1
  14.在堆内存中开辟空间,为Zi类分配内存地址.
  15.在堆内存中建立Zi对象的成员,并进行默认初始化,如果成员有被赋值的话,那么将赋值的成员显示初始化。
  16.将zi类的方法放入方法区
  17.执行zi类的构造代码块,所以打印的第三行是:Zi.enclosing_method()... zinum=24 num=12
  18.执行zi类的构造方法,Fu(int)所以打印的第四行是:Zi.Zi((String zi zi=) .... hello .... i=1

4.将Zi对象内存地址指向zi变量。

5.main方法执行结束

[6]抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。

[7]接口中的修饰成员符是固定的(默认的)。
成员常量:public static final
成员函数:public abstract

[8]多态中的特点
成员函数的特点:
编译时期,参阅引用类型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败
在运行期,参阅对象所属的类中是否有调用的方法。

成员变量的特点:
编译时期:参阅引用类型变量所属的类
在运行期:参阅引用类型变量所属的类

静态成员函数、静态成员变量的特点:
编译时期:参阅引用类型变量所属的类
在运行期:参阅引用类型变量所属的类

9.内部类,静态内部类,局部内部类,匿名内部类,没有实现接口和继承类的匿名内部类

内部类的特点:
内部类可以直接访问外部类的成员(外部类.this.成员),包括私有成员。
外部类要访问内部类中的成员必须要建立内部类的对象。

package cn.soldier.oop;

public class InnerDemo {
private String name = "InnerDemo";
private static int age = 1;

InnerDemo() {
Inner inner = new Inner();
System.out.println(inner.name);
}
// 内部类
class Inner {
private String name = "Inner";

Inner() {
System.out.println(InnerDemo.this.name);// 默认InnerDemo.this.,可以忽略不写
}
}
// 静态内部类
public static class InnerStatic {
void innerStatic() {
// 只能访问外部类的静态成员
// 非静态内部类中不可以定义静态成员
System.out.println(age);
}
}
public void method() {
final int method_age = 10;
// 局部内部类
class MethodInner {
void function() {
// 不可以被成员修饰符修饰 .
// 可以直接访问外部类中的成员和引用,但是不可以访问它所在的非final变量。
System.out.println(age);
System.out.println(name);
System.out.println(method_age);
}
}
new MethodInner().function();
}
public void method_1() {
// 匿名内部类
// 1.定义匿名内部类的前提:内部类必须继承一个类或实现接口
// 2.其实内部类就是一个匿名子类对象。而且这个对象有点胖
new AbsDemo() {
    void show() {
    System.out.println("InnerDemo.method_1().show()+ name=" + name);
    }

    void show1() {
      System.out.println("InnerDemo.method_1().show1()+ name=" + name);
    }
    }.show();
//
  new AbsDemo() {
void show() {
System.out.println("InnerDemo.method_1().show()+ name=" + name);
}

void show1() {
System.out
.println("InnerDemo.method_1().show1()+ name=" + name);
}
}.show1();
}
}
abstract class AbsDemo {
abstract void show();
}
class OuterDemo {
public static void main(String[] args) {
InnerDemo.Inner inner = new InnerDemo().new Inner();
new InnerDemo.InnerStatic().innerStatic();
new InnerDemo().method();
new InnerDemo().method_1();
  
  }

}


// 面试题:请构造出下面的写法; *
  new Method().method().method();
  Method.method().method();
  // 分析如下:
  Method类中有一个静态方法method()
  method()这个方法运算后返回结果是一个对象,而且是一个静态匿名类对象,
   该静态匿名类对象继承一个类或实现一个接口,该类或接口里面有一个method()方法。

class Method {
  static class _Inner implements Imethod {
    public void method() {
    System.out.println("Method._Inner.method(),呵呵");
  }
  }

  

  static _Inner method() {
    return new _Inner();
  }
}

interface Imethod {
  abstract void method();
}


// 面试题:写出一个没有实现接口和继承类的匿名内部类对象
new Object() {//这是Object子类对象,是没有实现接口和继承类的匿名内部类对象

  public void function() {

    System.out.println("OuterDemo.main()");

  }
}.function();



10.
Trowable
|--Error
|-- ...
|--Exception
|--ApplicationException
|--PrintException
|--ArithmeticException
|--ArrayIndexOutOfBoundsException
|--RuntimeException
|-- ...

异常声明 throws
//throws 关键字声明了该功能有可能会出现问题。需要调用者处理。
void show() throws Exception{}

异常声明 throw
void show() throws Exception{
if(true){
throw new RuntimeException();
}
}

throws 与 throw 的区别
throws 定义在函数上 ,后面跟的是异常类,可以多个以逗号隔开。
throw 定义在函数中 ,后面跟的是异常对象。


RuntimeException 及其子类 如果在函数里被抛出可以不用再函数声明。
|--ArithmeticException
|--NullPointerException
|--IndexOutOfBoundsException
|-- ...
之所以不用声明,是因为该异常的发生,不需要让调用者处理。当发生异常时,
设计者希望程序停止,因为出现了无法继续运算的情况。希望通过程序停止后,
使用者对该问题进行修正。

异常在子父类覆盖中的处理。
1.子类覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者改异常的子类。
2.如果父类方法抛出了多个异常,那么子类在覆盖该方法是,只能抛出父类异常的子集(比父类少或相等)。
3.如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法是,也不可抛出异常,也就是说,如果子类方法发生了异常,只能自己消化不能抛出。

finally 只有一种情况不会执行,
当执行到 System.exit(0);finally{}时不会执行。

自定义异常
继承Exception
或者RuntimeException
//1.具备可抛性,2,具备操作异常的共性方法。
Class MyException extends Exception
{
MyException(String message)
{
super(message);
}
}

11.多线程
多线程的线程安全问题:
当多个语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分执行完,另一个线程参与进来执行,导致共享数据的错误。

解决线程安全问题,保证共享数据的操作是线程同步的。

同步的前提:1.一个进程中,必须由两个或者两个以上的线程。
2.多个线程使用的是同一个锁

同步函数的锁是this
静态同步函数的锁是Class对象

死锁问题:同步中嵌套同步,锁不同
public class ThreadDemo {
public static void main(String[] args) {
new Thread(new Testlock(true)).start();
new Thread(new Testlock(false)).start();
}
}

class Testlock implements Runnable {
private boolean flag;

Testlock(boolean flag) {
this.flag = flag;
}

public void run() {


if (flag) {
synchronized (Mylock.locka) {
System.out.println("if locka");
synchronized (Mylock.lockb) {
System.out.println("if lockb");
}
}

} else {
synchronized (Mylock.lockb) {
System.out.println("else lockb");
synchronized (Mylock.locka) {
System.out.println("else locka");
}
}

}
}
}

class Mylock {
static Object locka = new Object();
static Object lockb = new Object();
}
线程间通讯
wait()、notify()、notifyAll()为什么要定义在Object类中?
1.这些方法存在于同步中。
2.使用这些方法是必须要标识所属的同步锁。
3.锁是可以是任意对象,所以任意对象调用的方法一定要定义在Object类中。

wait()和sleep()有什么区别
wait释放资源,释放锁
sleep释放资源,不释放锁

package cn.soldier.oop;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

//创建Thread,小秀一手
public class ThreadDemo {
    public static void main(String[] args) {

        new TestThread("逗比 ").start();
        new TestThread("呵呵 hehe").start();

        //
        for (int i = 0; i < 100; i++) {
            System.out.println("ThreadDemo.main() -------- " + i);
        }

    }
}

class TestThread extends Thread {

    TestThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(this.getName()
                    + "-------TestThread.run() -------- " + i);
        }
    }

}

// 实现Runnable接口,使用synchronized解决多个线程操作共享数据的安全问题
public class ThreadDemo {
    public static void main(String[] args) {
        TickeRunnable tickeRunnable = new TickeRunnable();
        new Thread(tickeRunnable).start();
        new Thread(tickeRunnable).start();
    }
}

// class TickeThread extends Thread {
class TickeRunnable implements Runnable {

    private int tick = 100;
    Object obj = new Object();

    public void run() {
        boolean flag = true;
        while (flag) {
            synchronized (obj) {
                if (tick > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                    }
                    System.out.println("Ticke:  " + tick-- + "号,被   "
                            + Thread.currentThread().getName() + "  卖了");
                } else {
                    flag = false;
                }
            }
        }
    }
}

public class ThreadDemo {
    public static void main(String[] args) {
        Cus cus = new Cus();
        new Thread(cus).start();
        new Thread(cus).start();
    }
}

class Bank {
    private int sum;

    public void add(int n) {
        synchronized (this) {
            sum = sum + n;
            System.out.println(Thread.currentThread().getName()
                    + "  Bank.add()--- sum=" + sum);
        }
    }
}

class Cus implements Runnable {
    private Bank bank = new Bank();

    public void run() {
        for (int i = 0; i < 3; i++) {
            bank.add(100);
        }
    }
}

// 延迟加载的单例模式
class Single {
    private static Single s = null;

    private Single() {
    }

    public static Single getInStance() {

        if (s == null) {
            // 这是关键,减少同步次数,提高效率
            synchronized (Single.class) {
                // 锁。该类所属的字节码文件对象
                if (s == null) {
                    s = new Single();
                }
            }
        }
        return s;
    }
}

// 饿汉试单例模式
class Single1 {
    private static final Single1 s = new Single1();

    private Single1() {
    }

    public static Single1 getInStance() {
        return s;
    }
}

// 死锁
public class ThreadDemo {
    public static void main(String[] args) {
        new Thread(new Testlock(true)).start();
        new Thread(new Testlock(false)).start();
    }
}

class Testlock implements Runnable {
    private boolean flag;

    Testlock(boolean flag) {
        this.flag = flag;
    }

    public void run() {

        if (flag) {
            synchronized (Mylock.locka) {
                System.out.println("if locka");
                synchronized (Mylock.lockb) {
                    System.out.println("if lockb");
                }
            }

        } else {
            synchronized (Mylock.lockb) {
                System.out.println("else lockb");
                synchronized (Mylock.locka) {
                    System.out.println("else locka");
                }
            }

        }
    }
}

class Mylock {
    static Object locka = new Object();
    static Object lockb = new Object();
}

public class ThreadDemo {
    public static void main(String[] args) {

        Resource resource = new Resource();
        Producer producer = new Producer(resource);
        Consumer consumer = new Consumer(resource);

        new Thread(producer).start();
        new Thread(consumer).start();
        new Thread(producer).start();
        new Thread(consumer).start();

    }
}

class Resource {
    private String name;
    private int count = 1;
    private boolean flag = false;

    public synchronized void set(String name) {
        while (flag) {
            try {
                this.wait();
            } catch (Exception e) {
            }
        }
        this.name = name + "--" + count++;
        System.out.println(Thread.currentThread().getName() + "--生产者--"
                + this.name);
        flag = true;
        this.notifyAll();

    }

    public synchronized void out() {
        while (!flag) {
            try {
                this.wait();
            } catch (Exception e) {
            }
        }
        System.out.println(Thread.currentThread().getName()
                + "--------消费者-------" + this.name);
        flag = false;
        this.notifyAll();

    }
}

class Producer implements Runnable {
    private Resource resource;

    Producer(Resource resource) {
        this.resource = resource;
    }

    public void run() {
        while (true) {
            resource.set("逗比");

        }
    }
}

class Consumer implements Runnable {
    private Resource resource;

    Consumer(Resource resource) {
        this.resource = resource;
    }

    public void run() {
        while (true) {
            resource.out();
        }
    }
}

public class ThreadDemo {
    public static void main(String[] args) {

        Resource resource = new Resource();
        Producer producer = new Producer(resource);
        Consumer consumer = new Consumer(resource);

        new Thread(producer).start();
        new Thread(consumer).start();
        new Thread(producer).start();
        new Thread(consumer).start();

    }
}

class Resource {
    private final Lock lock = new ReentrantLock();// 拿到锁
    private final Condition condition_producer = lock.newCondition();// 生产者的监视器
    private final Condition condition_consumer = lock.newCondition();// 消费者的监视器
    //
    private String name;
    private int count = 1;
    private boolean flag = false;

    public void set(String name) throws InterruptedException {
        lock.lock();
        try {
            if (flag)
                condition_producer.await();
            this.name = name + "--" + count++;
            System.out.println(Thread.currentThread().getName() + "--生产者--"
                    + this.name);
            flag = true;
            condition_consumer.signal();
        } finally {
            lock.unlock();
        }
    }

    public void out() throws InterruptedException {
        lock.lock();
        try {
            if (!flag)
                condition_consumer.await();
            System.out.println(Thread.currentThread().getName()
                    + "--------消费者-------" + this.name);
            flag = false;
            condition_producer.signal();
        } finally {
            lock.unlock();
        }

    }
}

class Producer implements Runnable {
    private Resource resource;

    Producer(Resource resource) {
        this.resource = resource;
    }

    public void run() {
        while (true) {
            try {
                resource.set("逗比");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

class Consumer implements Runnable {
    private Resource resource;

    Consumer(Resource resource) {
        this.resource = resource;
    }

    public void run() {
        while (true) {
            try {
                resource.out();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
原文地址:https://www.cnblogs.com/lhy_2011/p/4042051.html