java进阶day34多线程、反射机制、类加载机制

28 篇文章 0 订阅

p800 守护线程概述

在这里插入图片描述

p801 实现守护线程

package com.bjpowernode.java.thread;

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

        BackDataThread bdt = new BackDataThread();
        bdt.setName("备份数据的线程");
        bdt.setDaemon(true);
        bdt.start();



        //主线程是用户线程
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+"----->"+i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

        //现在备份线程还不是守护线程。如果想要把备份线程设置为守护线程,很简单
        //只需要在启动之前加一句
        //        bdt.setDaemon(true);即可
        //设置之后,用户线程结束之后,守护线程自动结束。
        //设置之后,用户线程结束之后,守护线程自动结束。

    }
}
class BackDataThread extends Thread{

    @Override
    public void run() {
        int i= 0;
        //即使是死循环,但是作为守护线程,等到用户线程结束时,他也会自动结束
        while(true){
            System.out.println(Thread.currentThread().getName()+"------------>"+(++i));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

p802 定时器概述

在这里插入图片描述

p803 实现定时器

在这里插入图片描述
在这里插入图片描述

自定义类实现接口

package com.bjpowernode.java.thread;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class TimerTest {

    public static void main(String[] args) throws ParseException {
        //创建定时器对象
        //Timer timer = new Timer(true);参数true表示以守护线程运行
        Timer timer = new Timer();

        //创建定时任务
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //设置第一次时间为2020年4月2日九点半
        Date firstTime = sdf.parse("2021-04-02 09:30:00");

        timer.schedule(new LogTimerTask(),firstTime,1000*10);

    }
}
class LogTimerTask extends TimerTask{

    /**
     * The action to be performed by this timer task.
     */
    @Override
    public void run() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String strTime = sdf.format(new Date());
        System.out.println(strTime+":成功完成了一次数据备份!");
    }
}

匿名内部类

import java.util.TimerTask;

public class TimerTest02 {

    public static void main(String[] args) throws ParseException {
        //创建定时器对象
        //Timer timer = new Timer(true);参数true表示以守护线程运行
        Timer timer = new Timer();

        //创建定时任务
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //设置第一次时间为2020年4月2日九点半
        Date firstTime = sdf.parse("2021-04-02 09:30:00");

        timer.schedule(new TimerTask(){

            /**
             * The action to be performed by this timer task.
             */
            @Override
            public void run() {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String strTime = sdf.format(new Date());
                System.out.println(strTime+":成功完成了一次数据备份!");
            }
        },firstTime,1000*10);

    }
}

p804 实现线程的第三种方式

在这里插入图片描述
在这里插入图片描述

package com.bjpowernode.java.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/*
实现线程的第三种方式:callable(),可以得到线程的返回值。
 */
public class ThreadTest15 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        //第一步:创建一个"未来任务类"对象
        //参数很重要,需要实现一个Callable接口的实现类对象
        FutureTask futureTask = new FutureTask(new Callable() {
            @Override
            public Object call() throws Exception {//call()方法相当于run()方法
                //线程执行任务。可能会有一个执行结果。
                //模拟执行
                System.out.println("call method begin");
                Thread.sleep(1000*10);
                System.out.println("call method end");
                int a = 100;
                int b = 200;
                return a+b;//return自动装箱后返回Integer类型
            }
        });

        //创建线程对象
        Thread t = new Thread(futureTask);//新建线程对象的时候将上面的未来任务传进来
        t.setName("ttt");
        t.start();

        //在主线程如何获取t线程的返回结果
        //get()方法的执行会导致当前线程阻塞,效率较低。但是他可以拿到返回结果。
        Object obj = futureTask.get();



        //但是现在有一个问题,main()方法想要执行必须等待get方法结束
        //而get方法又要等待另一个线程执行结束。
        //另一个线程执行需要时间
        System.out.println("hello main");

    }
}

p805 wait和notify方法(生产者和消费者)

在这里插入图片描述

p806 生产者和消费者模式

在这里插入图片描述
在这里插入图片描述

p807 生产者和消费者模式代码实现【生产1个,消费1个】

package com.bjpowernode.java.thread;

import java.util.ArrayList;
import java.util.List;

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

        //创建一个仓库对象,共享的
        List list = new ArrayList();

        //创建两个线程对象
        Thread t1 = new Thread(new Producer(list));
        Thread t2 = new Thread(new Consumer(list));

        //设置线程名字
        t1.setName("t1");
        t2.setName("t2");

        //启动
        t1.start();
        t2.start();


    }
}
class Producer implements Runnable{
    private List list;

    public Producer(List list) {
        this.list = list;
    }

    @Override
    public void run() {
        while(true){
            //给仓库对象list加锁
            synchronized (list){
                //如果list集合大于0,那么就等待,不需要生产了。
                if (list.size() > 0){
                    try {
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //如果if条件不成立,那就说明list集合为空,开始生产
                Object obj = new Object();
                list.add(obj);
                System.out.println(Thread.currentThread().getName()+"---->"+obj);

                //唤醒消费者进行消费
                list.notifyAll();

            }
        }
    }
}
class Consumer implements Runnable{

    private List list;

    public Consumer(List list) {
        this.list = list;
    }
    @Override
    public void run() {
        while(true){
            synchronized (list){
                //如果list集合等关于0,那么就等待,不能继续消费。
                if (list.size() == 0){
                    try {
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //如果if条件不成立,那就说明list集合不为空,开始消费
                Object obj = list.remove(0);//参数为数组中的元素下标。
                System.out.println(Thread.currentThread().getName()+"---->"+obj);

                //唤醒生产者开始生产
                list.notifyAll();
           }
        }
    }
}

p808 生产者和消费者模式代码理解【平衡】在这里插入图片描述

p809 布置线程作业

package com.bjpowernode.java.homework;

/*
运行不成功,下次找答案再试试
 */
import java.util.ArrayList;
import java.util.List;

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

        //创建一个仓库对象,共享的
        Integer num = 0;

        //创建两个线程对象
        Thread t1 = new Thread(new Number(num));
        Thread t2 = new Thread(new Number(num));

        //设置线程名字
        t1.setName("t1");
        t2.setName("t2");

        //启动
        t1.start();
        t2.start();

    }
}
class Number implements Runnable{
    private Integer num;

    public Number(int num) {
        this.num = num;
    }

    @Override
    public void run() {
        while(true){
            synchronized (num){

                //如果是偶数,那就等待
                if (num % 2 == 0){
                    try {
                        num.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //如果是奇数,那就输出
                System.out.println(Thread.currentThread().getName()+"--->"+num);
                num++;
                num.notifyAll();
            }
            synchronized (num){

                //如果是奇数,那就等待
                if (num % 2 != 0){
                    try {
                        num.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //如果是偶数,那就输出
                System.out.println(Thread.currentThread().getName()+"--->"+num);
                num++;
                num.notifyAll();

            }
        }
    }
}

p810 反射机制

在这里插入图片描述
在这里插入图片描述

p811 反射机制可以草操作字节码文件【获取字节码的第一种方式】

package com.bjpowernode.java.reflect;

/*
反射机制可以操作字节码文件,但是怎么拿到字节码文件?
如何拿到字节码文件?
 */
public class ReflectTest01 {
    public static void main(String[] args) {


        try {
            Class c1 = Class.forName("java.lang.String");
            Class c2 = Class.forName("java.util.Dtae");
            Class c3 = Class.forName("java.lang.Integer");
            Class c4 = Class.forName("java.lang.System");
            
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

p812 获取字节码的第二种方式

在这里插入图片描述
在这里插入图片描述

p813 获取字节码的第三种方式

package com.bjpowernode.java.reflect;

import java.util.Date;

/*
反射机制可以操作字节码文件,但是怎么拿到字节码文件?
如何拿到字节码文件?
 */
public class ReflectTest01 {
    public static void main(String[] args) {

        Class c1 = null;
        Class c2 = null;
        try {
            c1 = Class.forName("java.lang.String");
            c2 = Class.forName("java.util.Date");
            Class c3 = Class.forName("java.lang.Integer");
            Class c4 = Class.forName("java.lang.System");

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


        //java中任何一个对象都有一个方法::getClass()
        String s = "abc";
        Class x = s.getClass();
        System.out.println(x);//class java.lang.String.x表示String类型。x表示String.class字节码文件
        System.out.println(c1 == x);//双等号判断内存地址,c1和x都表示String.class字节码文件


        Date time = new Date();
        Class y = time.getClass();
        System.out.println(y);
        System.out.println(c2 == y);//true.c2和y在方法区都指向Date.class字节码文件。


        //java中任何一种类型,包括基本数据类型给,都有.class属性
        Class z = String.class;
        Class k = Date.class;
        Class f = int.class;
        Class e = double.class;

        System.out.println(x == z);
    }
}

在这里插入图片描述

p814 通过反射机制实例化对象

package com.bjpowernode.java.reflect;

import com.bjpowernode.java.bean.User;

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

        //第一种方法创建对象,实例化对象。
        User user = new User();
        System.out.println(user);

        //第二种方法创建对象
        try {
            Class c = Class.forName("com.bjpowernode.java.bean.User");
            Object o = c.newInstance();
            System.out.println(o);


        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

p815 通过读属性文件实例化对象

在这里插入图片描述
在这里插入图片描述

测试文件

package com.bjpowernode.java.reflect;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Properties;

/*
验证反射机制创建对象的灵活性
 */
public class ReflectTest03 {
    public static void main(String[] args) throws Exception {

        //通过I/O流读取配置文件
        FileReader reader = new FileReader("Chapter25_Reflect/classinfo.properties");

        //创建属性类对象pro
        Properties pro = new Properties();

        //加载
        pro.load(reader);

        //关闭流
        reader.close();

        //通过key获取value
        String className = pro.getProperty("className");

        //拿到类名
        //System.out.println(className);

        //通过反射机制创建对象
        Class c = Class.forName(className);
        Object obj = c.newInstance();
        System.out.println(obj);



    }
}

配置文件

#className=com.bjpowernode.java.bean.User
className=java.util.Timer

p816 只让静态代码块执行可以使用forName

在这里插入图片描述

package com.bjpowernode.java.reflect;
/*如果只希望一个类的静态代码块执行,其他代码一律不执行,那么就使用:
    Class.forName("完整类名")

   这个方法的执行会导致类加载,类加载时,静态代码块执行。
 */
public class ReflectTest04 {
    public static void main(String[] args) {
//        Myclass mc = new Myclass();
        try {
            Class.forName("com.bjpowernode.java.reflect.Myclass");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

p817 获取类路径下文件的绝对路径

在这里插入图片描述
在这里插入图片描述

package com.bjpowernode.java.reflect;

import java.io.FileNotFoundException;
import java.io.FileReader;

public class AbsolutePath {
    public static void main(String[] args) throws Exception {
        //这种方式的路径缺点是:移植性差,在IDEA中默认的当前路径是project的根
        //这个代码离开IDEA之后,换到其他位置,这个路径就无效了
//        FileReader reader = new FileReader("Chapter25_Reflect");


        //通用路径,这样编写,即使代码换位置之后,也能找到。
        //前提是必须在类路径下
        //什么是类路径?凡是在src下的都是类路径【记住】
        //src是类路径的根路径

        //当前线程对象【Thread.currentThread()】的类加载器对象【getContextClassLoader】的资源【getResource()】的路径
        String path = Thread.currentThread().getContextClassLoader()
                .getResource("classinfo2.properties").getPath();

        //获取一个文件的绝对路径
        System.out.println(path);

        String path2 = Thread.currentThread().getContextClassLoader()
                .getResource("com/bjpowernode/java/bean/db.properties").getPath();

        //获取一个文件的绝对路径
        System.out.println(path2);
    }
}

p818 以流的形式直接返回

在这里插入图片描述

package com.bjpowernode.java.reflect;

import java.io.FileReader;
import java.nio.file.Path;
import java.util.Properties;

public class IoPropertiesTest {
    public static void main(String[] args) throws Exception {
        //获取绝对路径【通用方式】

        String path = Thread.currentThread().getContextClassLoader()
                .getResource("classinfo2.properties").getPath();


        //System.out.println(path);
        FileReader reader = new FileReader(path);
        Properties pro = new Properties();
        pro.load(reader);
        reader.close();

        //通过Key获取value
        String className = pro.getProperty("className");
        System.out.println(className);

    }
}

在这里插入图片描述

package com.bjpowernode.java.reflect;

import java.io.FileReader;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.Properties;

public class IoPropertiesTest {
    public static void main(String[] args) throws Exception {
        //获取绝对路径【通用方式】
//
//        String path = Thread.currentThread().getContextClassLoader()
//                .getResource("classinfo2.properties").getPath();
//
//
//        //System.out.println(path);
//        FileReader reader = new FileReader(path);

        //直接以流的形式返回

        InputStream reader = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("classinfo2,properties");

        Properties pro = new Properties();
        pro.load(reader);
        reader.close();

        //通过Key获取value
        String className = pro.getProperty("className");
        System.out.println(className);

    }
}

p819 资源绑定器

java.util包下提供了一个资源绑定器,便于获取属性配置文件下中的内容
资源绑定器只能绑定xxx.properties配置文件,并且这个文件必须在类路径下,文件扩展名也必须是properties
并且在写路径的时候,路径后面的扩展名不能写。

package com.bjpowernode.java.reflect;

import java.util.ResourceBundle;

public class ResourceBundleTest {
    public static void main(String[] args) {
        //注意都是以src作为起点。
        ResourceBundle bundle = ResourceBundle.getBundle("classinfo2");

        String className = bundle.getString("className");
        System.out.println(className);

        //都是以src下作为起点
        ResourceBundle bundle2 = ResourceBundle.getBundle("com/bjpowernode/java/bean/db");
        String className2 = bundle2.getString("className");
        System.out.println(className2);



    }
}

p820 类加载器概述【扩展】

在这里插入图片描述

p821 双亲委派机制【扩展】

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值