Java深层知识点(下)

目录

线程

创建

继承thread类

重写runnable接口

callable接口(jdk5.0)

API

 县城安全

 问题模拟

线程同步

思想

同步代码块

同步方法

Lock对象(jdk5.0)

线程通信*

 线程池!!!

API、参数说明

  处理Runnable任务

   处理Callable任务

Executors工具类构建线程池对象

 定时器

创建

缺陷1:等待~~~~~~~无法按时执行

缺陷3:一个死了全死了

弥补

线程六个状态*

 网络(暂时跳过)

InetAddress

API

 单元测试

JUnit

反射

获取class类的对象

获取构造器对象

获取完做什么

还有获取成员变量和方法的api,没时间了先不看了,原理大差不差

反射作用

绕过编译阶段给集合添加数据

注解

自定义注解

 元注解

 注解解析

注解应用:模拟Junit框架

动态代理!!

创建

 流程

 案例***

XML

概述

 约束

DTD

schema

 xml解析

 检索技术——XPath

设计模式

工厂

装饰


线程

创建

继承thread类

public class m1_extendsThread {
    public static void main(String[] args) {
        MyThread t = new MyThread();
        t.start();//执行的还是run

        for (int i = 0; i < 5; i++) 
            System.out.println("main线程输出");
    }
}

/*
* 1.定义一个线程类继承线程
* */
class MyThread extends Thread{
    //重写run方法
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) 
            System.out.println("自定义线程");
    }
}

@ 不要把主线程任务放在子线程之前了。
        这样主线程一直是先跑完的,相当于是一个单线程的效果了

@ 继承一个之后继承不了其他,有局限性

重写runnable接口

public class m2_runnable {
    public static void main(String[] args) {
        MyRun m = new MyRun();
        new Thread(m).start();
        for (int i = 0; i < 5; i++) 
            System.out.println("main线程");
    }
}
class MyRun implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) 
            System.out.println("子线程输出");
    }
}

@ 可以实现多个接口,加继承

@ 但是拿不到run的返回结果

callable接口(jdk5.0)

public class m3_Callable {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyCall r = new MyCall(100);
        FutureTask<String> f1 = new FutureTask<>(r);
        Thread t = new Thread(f1);
        t.start();
        System.out.println(f1.get());
    }
}


class MyCall implements Callable<String>{
    private int n;
    private int sum;
    public MyCall(int n) {
        this.n = n;
    }

    @Override
    public String call() throws Exception {
        for (int i = 0; i <=n; i++) {
            sum+=i;
        }
        return sum+"";
    }
}

优点:线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强。
可以在线程执行完毕后去获取线程执行的结果。 

API

 县城安全

多个线程同时操作同一个共享资源的时候可能会出现业务安全问题,称为线程安全问题。(取钱,买票············)

 问题模拟

public class danger_moni {
    public static void main(String[] args) {
        Account pool = new Account("alibaba" ,100000);
        new DrawThread(pool, "xiaohong").start();
        new DrawThread(pool, "xiaoming").start();
    }
}

class DrawThread extends Thread{
    private Account ac;
    public DrawThread(Account account, String name){
        super(name);
        this.ac = account;
    }

    @Override
    public void run() {
        ac.draw(100000);
    }
}

class Account{
    private String id;
    private int money;

    public Account(String id, int money) {
        this.id = id;
        this.money = money;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }

    public void draw(int i) {
        String name = Thread.currentThread().getName();
        if(this.money >= i){
            System.out.println("吐了10w to "+name);
            this.money-=i;
            System.out.println(name+"取完,余额:"+this.money);
        }else
            System.out.println("余额不足");



        this.money-=i;
    }
}

线程同步

思想

加锁,把共享资源进行上锁,每次只能一个线程进入访问完毕以后解锁,然后其他线程才能进来。

同步代码块

同步方法

作用:把出现线程安全问题的核心方法给上锁。
原理:每次只能一个线程进入,执行完毕以后自动解锁,其他线程才可以进来执行。

@ 同步方法其实底层也是有隐式锁对象的,只是锁的范围是整个方法代码。
@ 如果方法是实例方法:同步方法默认用thS作为的锁对象。但是代码要高度面向对象!
@ 如果方法是静态方法:同步方法默认用类名.class作为的锁对象。

Lock对象(jdk5.0)

        try {
            if(this.money >= i){
                System.out.println("吐了10w to "+name);
                this.money-=i;
                System.out.println(name+"取完,余额:"+this.money);
            }else
                System.out.println("余额不足");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            l.unlock();
        }

线程通信*

package c4_thread_communication;

public class CommuDemo {
    public static void main(String[] args) {
        Account ac = new Account("ChinaBank", 0);
//        取钱线程代表
        new DrawThread(ac, "xiaoming").start();
        new DrawThread(ac, "xiaohong").start();
//        三个存钱线程代表
        new SaveThread(ac, "一die").start();
        new SaveThread(ac, "2die").start();
        new SaveThread(ac, "3die").start();
    }
}

class SaveThread extends Thread{
    private Account ac;
    public SaveThread(Account account, String name){
        super(name);
        this.ac = account;
    }
    @Override
    public void run() {
        while (true) {
            ac.save(500000);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
package c4_thread_communication;

public class Account {
    private String id;
    private int money;

    public Account(String id, int money) {
        this.id = id;
        this.money = money;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }


    public synchronized void draw(int i) {
        String name = Thread.currentThread().getName();
        try {
            if (this.money>=i){
                this.money-=i;
                System.out.println(name+"取完还有"+money);
                //唤醒存钱线程
                this.notifyAll();//先唤醒所有进程
                this.wait();//再锁对象让当前线程进入等待
            }else {
                //唤醒存钱线程
                this.notifyAll();//先唤醒所有进程
                this.wait();//再锁对象让当前线程进入等待


            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void save(int i) {
        String name = Thread.currentThread().getName();
        try {
            if (this.money<100){
                this.money+=i;
                System.out.println(name+"save完还有"+money);

                //唤醒存钱线程
                this.notifyAll();//先唤醒所有进程
                this.wait();//再锁对象让当前线程进入等待
            }else {
                //唤醒存钱线程
                this.notifyAll();//先唤醒所有进程
                this.wait();//再锁对象让当前线程进入等待


            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

package c4_thread_communication;

public class DrawThread extends Thread{
    private Account ac;
    public DrawThread(Account account, String name){
        super(name);
        this.ac = account;
    }

    @Override
    public void run() {
        while (true) {
            ac.draw(100000);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }
}

 线程池!!!

线程池就是一个可以复用线程的技术。

        @ 如果用户每发起一个请求,后台就创建一个新线程来处理,下次新任务来了又要创建新线程,而创建新线程的开销是很大的,这样会严重影响系统的性能。

API、参数说明

  处理Runnable任务

public class PoolDemo0 {
    public static void main(String[] args) {
        /*
        * public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
                              * */
        ExecutorService e = new ThreadPoolExecutor(3,5,5, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());

        Runnable r = new MyRun();
        e.execute(r);
        e.execute(r);
        e.execute(r);//三个线程与任务绑定

        e.execute(r);
        e.execute(r);
        e.execute(r);
        e.execute(r);
        e.execute(r);//五个进入了任务队列

        e.execute(r);//再来创建新线程
        e.execute(r);//再来创建新线程

        e.execute(r);//再来拒绝新线程
/*
* [Running, pool size = 5, active threads = 5, queued tasks = 5, completed tasks = 0]
	* */
        e.shutdown();
    }
}

class MyRun implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName()+"输出第"+i);

        }
        try {
            Thread.sleep(100000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

   处理Callable任务

public class PoolDemo1 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService e = new ThreadPoolExecutor(3,5,5, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());

        Future<String> f1 = e.submit(new MyCall(100));
        Future<String> f2 = e.submit(new MyCall(200));
        Future<String> f3 = e.submit(new MyCall(300));
        Future<String> f4 = e.submit(new MyCall(400));
        Future<String> f5 = e.submit(new MyCall(500));

        System.out.println(f1.get());
        System.out.println(f2.get());
        System.out.println(f3.get());
        System.out.println(f4.get());
        System.out.println(f5.get());
    }
}

class MyCall implements Callable{
    private int n;

    public MyCall(int n) {
        this.n = n;
    }

    @Override
    public String call() throws Exception {
        int sum = 0;
        for (int i = 0; i < n; i++) {
            sum+=n;
        }
        return Thread.currentThread().getName()+"结果"+sum;
    }
}

Executors工具类构建线程池对象

 定时器

创建

        //创建定时器对象
        Timer t = new Timer();
        //执行方法
        t.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"AAA"+new Date());
            }
        }, 3000, 1000);//delay延迟,period周期执行

缺陷1:等待~~~~~~~无法按时执行

        t.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"AAA"+new Date());
                try {
                    // 这个县城睡了一会导致下一个
                    // 县城无法及时按指定时间运行
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

            }
        }, 3000, 1000);//delay延迟,period周期执行

        t.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"BBB"+new Date());
            }
        }, 3000, 1000);//delay延迟,period周期执行

缺陷3:一个死了全死了

        t.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"AAA"+new Date());
                System.out.println(10/0);//单线程,这个死了别的正常也死了

            }
        }, 3000, 1000);//delay延迟,period周期执行

        t.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"BBB"+new Date());
            }
        }, 3000, 1000);//delay延迟,period周期执行

弥补

        ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);

        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+" AAA"+new Date());
                try {
                    Thread.sleep(5000);//这里睡觉不影响下面县城执行
                                             //这里错了死掉也不影响
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }, 0, 2, TimeUnit.SECONDS);

        pool.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+" BBB"+new Date());
            }
        }, 0, 2, TimeUnit.SECONDS);

线程六个状态*

 网络(暂时跳过)

InetAddress

API

 单元测试

单元测试就是针对最小的功能单元编写测试代码,Java程序最小的功能单元是方法,因此,单元测试就是针对Java方法的测试,进而检查方法的正确性。

JUnit

JUnit是使用Java语言实现的单元测试框架,它是开源的
此外,几乎所有的IDE工具都集成了Unit,这样我们就可以直接在IDE中编写并运行Unit测试

反射

反射是指对于任何一个Class:类,在"运行的时候"都可以直接得到这个类全部成分。

这种运行时动态获取类信息以及动态调用类中成分的能力称为ava语言的反射机制。 

弹幕:类对象是人类,类的对象是人 

获取class类的对象

        Class c = Class.forName("c2_reflect.Student");
        System.out.println(c);

        Class c1 = Student.class;
        System.out.println(c1);

        Student s = new Student();
        Class c2 = s.getClass();
        System.out.println(c2);    //全是class c2_reflect.Student

获取构造器对象

    @Test
    public void getpub(){
        Class c1 = Student.class;
        Constructor[] constructors = c1.getConstructors();
        for (Constructor constructor:constructors){
            System.out.println(constructor.getName()+" 参数: "+constructor.getParameterCount());
        }
    }
    @Test
    public void getall(){
        Class c2 = Student.class;
        Constructor[] constructors = c2.getDeclaredConstructors();
        for (Constructor constructor:constructors){
            System.out.println(constructor.getName()+" 参数: "+constructor.getParameterCount());
        }
    }
    //定位单个构造器对象,按照参数个数定位,只能取public
    @Test
    public void getsingle() throws NoSuchMethodException {
        Class c3 = Student.class;
        Constructor constructor = c3.getConstructor();
        System.out.println(constructor.getName()+" 参数: "+constructor.getParameterCount());
    }
    //定位单个构造器对象,按照参数个数定位,取任何
    @Test
    public void getallsingle() throws NoSuchMethodException {
        Class c4 = Student.class;
        Constructor constructor = c4.getDeclaredConstructor(String.class, int.class);
        System.out.println(constructor.getName()+" 参数: "+constructor.getParameterCount());
    }

获取完做什么

        Class c4 = Student.class;

        Constructor constructor = c4.getDeclaredConstructor(String.class, int.class);
        System.out.println(constructor.getName()+" 参数: "+constructor.getParameterCount());
        Student s = (Student) constructor.newInstance("cxk", 20);
        System.out.println(s);

        //暴力反射,强行打开private的权限
        Constructor con_pri = c4.getDeclaredConstructor();//无参构造原来是private权限
        System.out.println(con_pri.getName()+" 参数: "+con_pri.getParameterCount());
        con_pri.setAccessible(true);
        Student s2 = (Student) con_pri.newInstance();

还有获取成员变量和方法的api,没时间了先不看了,原理大差不差

反射作用

绕过编译阶段给集合添加数据

        
        ArrayList<Integer> arr2  =new ArrayList<>();
        
        Class c = arr2.getClass();
        Method add = c.getDeclaredMethod("add", Object.class);
        boolean rs = (boolean) add.invoke(arr2, "cxk");//加入String
        

注解

对]ava中类、方法、成员变量做标记,然后进行特殊处理。

自定义注解

 元注解

就是注解注解的注解

   

 注解解析

解析???呵,就是把注解里的东西整出来,叫个解析!

public class Anli {
    @Test
    public void parseClass(){
        Class c = BookStore.class;
        if (c.isAnnotationPresent(Book.class)){
//            Annotation book = c.getDeclaredAnnotation(Book.class);
            Book book = (Book)c.getDeclaredAnnotation(Book.class);
            System.out.println(book.name());
            System.out.println(Arrays.toString(book.authors()));
            System.out.println(book.price());
        }
    }

    @Test
    public void parseMethod() throws Exception {
        Class c = BookStore.class;
        Method m = c.getDeclaredMethod("test");
        if (m.isAnnotationPresent(Book.class)){
            m.invoke(new BookStore());
        }
    }
}

@Book(name = "《python入门》", price = 90, authors = {"cxk", "moyan"})
class BookStore{
    @Book(name = "《三贱客》", price = 60, authors = {"cxk", "moyan"})
    public void test(){
        System.out.println("test");
    }

}


==========================================================

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Book {
    String name();
    int price() default 100;
    String[] authors();
}

注解应用:模拟Junit框架

public class fakeJunit {
    @MyTest
    public void test1(){
        System.out.println("===test1===");
    }
    public void test2(){
        System.out.println("===test2===");
    }
    @MyTest
    public void test3(){
        System.out.println("===test3===");
    }

    public static void main(String[] args) throws Exception{
        Class c = fakeJunit.class;
        Method[] methods = c.getDeclaredMethods();
        for (Method method :
                methods) {
            if(method.isAnnotationPresent(MyTest.class))
                method.invoke(new fakeJunit());
        }
    }
}

动态代理!!

创建

 流程

 案例***

Test

public class Test {
    public static void main(String[] args) {
        UserService user = new UserServiceImpl();//不走代理
        UserService user2 = ProxyUtil.getPro(user);//走代理
        System.out.println(user2.login("admin", "123456"));
        System.out.println(user2.selectUser());
        user2.delUser();
    }
}

UserService


public interface UserService {
    String login(String uid, String pwd);
    void delUser();
    String selectUser();
}

UserService实现

public class UserServiceImpl implements UserService{
    @Override
    public String login(String uid, String pwd) {
//        long startTime = System.currentTimeMillis();
        String rs = "登录失败!!!";
        if ("admin".equals(uid)&&"123456".equals(pwd))
            rs = "login success!";
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
//        long endTime = System.currentTimeMillis();
//        System.out.println("login 耗时:"+(endTime-startTime)/1000.0+"s");
        return rs;
    }

    @Override
    public void delUser() {
//        long startTime = System.currentTimeMillis();
        try {
            System.out.println("删除中。。。。");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
//        long endTime = System.currentTimeMillis();
//        System.out.println("del耗时:"+(endTime-startTime)/1000.0+"s");
    }

    @Override
    public String selectUser() {
//        long startTime = System.currentTimeMillis();
        String rs = "查询success";

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
//        long endTime = System.currentTimeMillis();
//        System.out.println("查询耗时:"+(endTime-startTime)/1000.0+"s");
        return rs;
    }
}

ProxyUtil

public class ProxyUtil {
    //这里换成T,啥对象都能统计运行时间
    public static UserService getPro(UserService obj){
        return (UserService) Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        long startTime = System.currentTimeMillis();
                        Object rs = method.invoke(obj, args);
                        long endTime = System.currentTimeMillis();
                        System.out.println(method.getName()+"耗时:"+(endTime-startTime)/1000.0+"s");
                        return rs;
                    }
                });

    }
}

Me:这个目的还是减少代码冗余,而且可以走代理增强原对象功能,比如:莫名其妙多了个统计时间的功能(和前边的模板模式一样?)

代理模式与模板模式 - 简书

XML

概述

XML是可扩展标记语言(eXtensible Markup Language)的缩写,它是是一种数据表示格式,可以描述非常复杂的数据结构,常用于传输和存储数据。

常作为软件的配置文件

 约束

文档约束:是用来限定文件中的标签以及属性应该怎么写。

DTD

自动补全

schema

①:编写schema约束文档,后缀必须是.xsd,具体的形式到代码中观看。
②:在需要编写的XML文件中导入该schema约束文档
③:按照约束内容编写XML文件的标签。

 xml解析

    public void parseXMLData() throws DocumentException {
        //解析器对象
        SAXReader saxReader = new SAXReader();
        //xml加载到内存
        InputStream is = Demo1.class.getResourceAsStream("/Contacts.xml");
        Document document = saxReader.read(is);

        //解析
        Element root = document.getRootElement();
        System.out.println(root.getName());

    }

java的相对路径在模块下./src/package/...... 


 检索技术——XPath

    @Test
    public void parse01() throws DocumentException {
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(xpath.class.getResourceAsStream("/Contacts2.xml"));

        List<Node> name = document.selectNodes("/contactList/contact/name");
        for (Node node :
                name) {
            Element e = (Element) node;
            System.out.println(e.getTextTrim());
        }
    }
    @Test
    public void parse02() throws DocumentException {
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(xpath.class.getResourceAsStream("/Contacts2.xml"));
        Element root = document.getRootElement();
        List<Node> name = root.selectNodes("./contact/name");
        for (Node node :
                name) {
            Element e = (Element) node;
            System.out.println(e.getTextTrim());
        }
    }

    @Test
    public void parse03() throws DocumentException {
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(xpath.class.getResourceAsStream("/Contacts2.xml"));
        List<Node> name = document.selectNodes("//name");//全文找name,无层级要求
        for (Node node :
                name) {
            Element e = (Element) node;
            System.out.println(e.getTextTrim());
        }
    }

设计模式

工厂

public class factory {
    public static void main(String[] args) {
        Computer c = creatComputer("huawei");
        c.start();
    }
    
    //厂里建好了对象
    public static Computer creatComputer(String info){
        switch (info){
            case "huawei":
                Computer c = new Huawei();
                c.setName("Mate 90");
                c.setPrice(9999);
                return c;
            case "mac":
                Computer c2 = new Mac();
                c2.setPrice(7999);
                c2.setName("Macbook");
                return c2;
            default:
                return null;
        }
    }
}

class Huawei extends Computer{
    @Override
    public void start() {
        System.out.println(this.getName()+" is a android");
    }
}

class Mac extends Computer{
    @Override
    public void start() {
        System.out.println(this.getName()+" is a apple");
    }
}

abstract class Computer{
    private String name;
    private int price;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public abstract void start();
}

装饰

创建一个新类,包装原始类,从而在新类中提升原来类的功能。

 注意修饰类里边的方法返回的是原始类的方法,调用过修饰类之后还会在调用原始类的方法

me:调用完第一层后的抽象类pri inputstream is就是传入的那个原始类fileinstream,回调原始类方法

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值