zoukankan      html  css  js  c++  java
  • 面向对象-多线程-异常机制-查漏补缺

    查漏补缺
    [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();
                }
            }
        }
    }
  • 相关阅读:
    【Selenium04篇】python+selenium实现Web自动化:文件上传,Cookie操作,调用 JavaScript,窗口截图
    【Selenium03篇】python+selenium实现Web自动化:元素三类等待,多窗口切换,警告框处理,下拉框选择
    【Selenium02篇】python+selenium实现Web自动化:鼠标操作和键盘操作!
    【Selenium01篇】python+selenium实现Web自动化:搭建环境,Selenium原理,定位元素以及浏览器常规操作!
    面试官看到一定会打我---软件测试工程师面试套路和暗语灵魂解密
    十年测试老鸟告诉你--自动化测试选JAVA还是选Python--写给还在迷茫中的朋友
    华为十年测试老鸟教您如何便写高质量的自动化测试工程师简历--看完必有所获
    工作中常用的Android系统ADB命令收集
    自动化测试中的三类等待深入剥析
    JAVA自动化之Junit单元测试框架详解
  • 原文地址:https://www.cnblogs.com/lhy_2011/p/4042051.html
Copyright © 2011-2022 走看看