Java反射机制和线程

2023-11-19

JAVA反射机制

已经加载过这个类,通过类名来找到这个类的所有相关信息。

  • 在运行时判断任意一个对象所属的类
  • 在运行时构造任意一个类的对象
  • 在运行时判断任意一个类所具有的成员变量和方法
  • 在运行时调用任意一个对象的成员变量和方法
  • 生成动态代理

反射相关的主要API:

  • java.lang.Class : 代表一个类
  • java.lang.reflect.Method : 代表类的方法
  • java.lang.reflect.Field : 代表类的成员变量
  • java.lang.flect.Constructor : 代表类的构造方法
// 获取Class对象
Class clazz = p.getClass();  // clazz里面包含了对象p所属类的有关信息
Class c1 = Person.class;  //  通过类名.class创建指定类的Class实例
Class c2 = Class.forName("包名.类名");  // 这个比较常用

// 获取
clazz.getName(); // 获取名称
clazz.getModifiers();  // 获取修饰符
Class[] paramClazz = clazz.getParameterTypes();  // 获取参数类型
Class superClazz = clazz.getSuperClass();  // 获取父类
Class[] interfaces = clazz.getInterfaces();  // 获取接口
Constructor[] cons = clazz.getConstructors();  // 获取public构造方法
Constructor[] cons = clazz.getDeclaredConstructors();  // 获取所有构造方法

// 动态调用构造器,创建对象,得到的都是Object,需要强制转换
Object obj = clazz.newInstance(); // 调用无参构造
Constructor con = clazz.getConstructor(String.class);
//获得参数为String的构造器。用DeclaredConstructors()可以获取private的构造方法。但是要在前面加一句,con.setAccessible(true); 解封装
Object obj = con.newInstance("lzq");  // 调用有参构造

// 动态获取方法、属性进行操作. 对私有属性、方法操作是,注意解封装
Method[] ms = clazz.getMethods();  // 获得全部公有方法,要获得私有的和上同理。
Field[] fs = clazz.getFiedls();  // 获取属性
Package p = clazz.getPackage();  //  获取包名
// 得到名称叫name 参数是String String 的方法。
Method m1 = clazz.getMethod("name",String.class,String.class);  
m1.invoke(obj, args);  // 参数1是需要实例化的对象,通过前面的构造可以得到,参数2是可变长的前面方法的实际参数,如果调用的方法有返回值,就接受并强制类型转换。
Field f = clazz.getFiedl("属性名");
f.set(stu, "aaaa");  // 设置stu对象的f属性值为aaaa
f.get(stu);  // 获取stu对象的f属性值,接收时注意类型转换。

// java 动态代理。注意 一个对象想要被代理,一定要有接口。
class ProxyOfTest implements InvocationHandler{
    Object obj;  // 被代理的对象
    public ProxyOfTest(Object obj){
        this.obj = obj;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) 
        throws Throwable{
        // 此处 在指定方法调用前,动态添加行为
        Object result = method.invoke(this.obj, args); //执行的是代理对象的制定方法。
        // 此处 在指定方法调用后,动态添加行为
        return result;
    }
}
InvocationHandler handler = new ProxyOfTest(test); //对test对象进行代理,得到代理对象hander
Test t = (Test)Proxy.newProxyInstance(handler.getClass().getClassLoader(), test.getClass().getInterfaces(), handler);  // 返回的是Object类型,是成功代理后的对象。
t.test(); 

Java线程

Java.lang.Thread类

  • run()
  • start()
/*创建线程*/
class TestThread extends Thread{ //继承Thread类的方式创建多线程
    @Override
    public void run() {
        //  多线程运行的代码
    }
}
Thread t0 = new TestThread();
t0.start();  // 启动线程,运行run方法,是异步执行


class TestRunnable implements Runnable{ // 实现Runnable接口
    @Override
    public void run() {
        //  多线程运行的代码
    }
}
Thread t1 = new Thread(new TestRunnable());
Thread t2 = new Thread(new TestRunnable(), "t2");// 也可以通过这个方式,第二个参数是线程名称。
t1.start();  

使用Runnable接口实现,避免了单继承的局限性,使得多个线程可以共享一个接口实现对象,处理同一份资源。

一些常用的方法:

String name = t.getName();  // 返回线程的名称 默认为Thread-0,Threa-1等
t.setName("name");  // 设置线程名称 
/*线程优先级:1-10; 数字越大越高,默认为5*/
int t.getPriority();
t.setPriority(int);
Thread.yeild();  // 线程让步:暂停自己的执行,把执行机会让给别的线程
Thread.sleep(1000);  // 当前线程睡眠1000ms。
t.join(); // 相当于把t的run方法插入到这个位置。阻塞了当前的main方法,先执行join进来的线程的代码
t.stop(); // 强制停止
boolean t.isAlive();  // 判断当前线程是否还活着。

线程同步

  • 使用同一个同步锁的才能实现线程同步。

  • 在public方法上加上关键字 synchronized 同步锁。锁的是某个对象不是仅仅某个方法。不同的对象是不同的同步锁。

  • 在static方法上加synchronized 同步锁。所有的实例化对象都是同一个同步锁。

  • 用 synchronized(this){ } 来锁某个代码块。如果在其他方法中也有synchronized(this)锁住的代码块,它们使用的是同一个同步锁。

  • class A{ 
        public void test(A a) {
            synchronized(a){
                // 这样子可以实现不同对象有不同的锁
            }
        }
    }
    

如果针对对象要加同步锁,那就加在方法上。
如果针对某一段代码需要加同步锁,那就直接在代码块上加同步锁。

线程通信

// a 为临界资源
a.wait(); // 阻塞
a.notify();  // 唤醒
a.notifyAll(); 
// 这三个方法只能用在有同步锁的方法里面

生产者和消费者

public class Test3{
    public static void main(String[] args){
        Clerk c = new Clerk();
        // 生产者
        new Thread(new Runnable(){
            @Override
            public void run(){
                synchronized (c) {
                    while(true){
                        if(c.productNum == 0){
                            // 生产产品
                            c.productNum++;
                            c.notify; // 唤醒消费者
                        }else{
                            c.wait(); // 让生产者等待
                        }
                    }
                }
            }
        },"生产者").start();
        
        // 消费者
        new Thread(new Runnable(){
            @Override
            public void run(){
                synchronized (c) {
                    while(true){
                        if(c.productNum > 0){
                            // 消费产品
                            c.productNum--;
                            c.notify; // 唤醒生产者
                        }else{
                            c.wait(); // 让消费者者等待
                        }
                    }
                }
            }
        },"消费者").start();
    }
}

public class Clerk{
    public static int productNum = 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java反射机制和线程 的相关文章

随机推荐

  • 微信小程序:自动生成打卡海报

    文章目录 1 前言 2 界面展示 3 部分代码展示以及原理解释 4 结语 完整项目下载 下载链接 1 前言 在当前的背单词小程序开发中 为满足用户学习完成后的展示需求 计划引入自动生成打卡海报功能 以提升用户参与度与推广效果 除了基本的海报
  • Window XP驱动开发(十三) 芯片功能驱动端 (代码实现,针对USB2.0 芯片CY7C68013A)

    转载请标明是引用于 http blog csdn net chenyujing1234 欢迎大家提出意见 一起讨论 需要源码的可以与我联系 针对USB2 0 芯片CY7C68013A FPGA实现的高速传输应用来写XP下的USB驱动程序 说
  • 医学图像配准工具Elastix的配置和入门

    一 Elastix介绍 Elastix是一个基于ITK开发的处理医学图像配准问题的工具 Elastix提供了很方便的命令行使用方式以供使用者进行配准应用 同时Elastix是开源的 并且采用模块式构成 可以根据源代码进行开发 或者添加新的模
  • 在LinuxBridge/OVS中使用VxLAN组网以及创建VTEP

    原文来自于 https blog lofyer org E5 9C A8linux bridge ovs E4 B8 AD E4 BD BF E7 94 A8vxlan E7 BB 84 E7 BD 91 E4 BB A5 E5 8F 8A
  • 【满分】【华为OD机试真题2023 JS】箱子之形摆放

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 箱子之形摆放 知识点数组 时间限制 1s 空间限制 128MB 限定语言 不限 题目描述 有一批箱子 形式为字符串 设为str 要求将这批箱子按从上到下以之形的顺序摆放在宽度为n
  • js的事件执行机制(Event loop)

    同步任务 执行主线程上排队执行的任务 只有前一个任务执行完毕 下一个任务才会开始执行 异步任务 不进入主线程 而进入 任务队列 task queue 的任务 只有 任务队列 通知主线程 某个异步任务可以执行了 该任务才会进入主线程执行 事件
  • docker安装nginx太多坑了,果断放弃

    以下是我本人的个人看法 如有不对可在评论区讨论交流 1 listen的端口受限于docker p的参数 一个nginx容器conf文件只能listen同一个端口 2 修改配置文件麻烦 还有docker exec进入到容器内部进行操作 当然
  • 医疗保健软件必备指南

    对许多人来说 软件可能是一种奢侈品 只会给生活在 21 世纪的人们带来一些额外好处 但有时 软件可能是救命稻草 起着生死攸关的作用 根据医疗行业的部分统计数据 我们清醒地发现 美国平均每年约有 25 万至 40 万患者死于本可预防的医疗差错
  • Qt队列的使用

    一 queue 队列 队列是一种先进先出的数据结构 是一个模板类 队列和栈是一种数据逻辑概念 即数据能进行的操作 主要区别是 队列先进先出 First In First Out 栈后进先出 链表和顺序表是一种数据存放方式 主要区别是 链表有
  • 向日葵远程连接Ubuntu出现 “连接中断“ 的解决方法

    向日葵远程连接Ubuntu出现 连接中断 的解决方法 https www cnblogs com wangling1820 p 13448397 html 方法一 参考博客1 https blog csdn net wzf20162016
  • styled-components 的用法

    用于给标签或组件添加样式 给标签或组件添加样式 import styled from styled components styled button 给button标签添加样式 const Button styled button back
  • opencv中归一化函数cv2.normalize()的原理讲解

    本篇文章参考博客 https blog csdn net kuweicai article details 78988886 功能 归一化函数 参数 Python cv2 normalize src dst alpha beta norm
  • 转:在内核里写i2c client 驱动的两种方式

    原文位置 https www cnblogs com simonshi archive 2011 02 24 1963426 html 在内核里写i2c client 驱动的两种方式 前文介 绍了利用 dev i2c 0在应用层完成对i2c
  • 局域网下ROS多机通信的网络连接配置

    1 在路由器设置中固定各机器IP地址 在浏览器中输入路由器的IP地址 例如TP LINK路由器的IP为 192 168 1 1 进入登录页面后 输入用户名和密码登录 用户名一般为admin 密码为自定义 在 基本设置 gt LAN设置 gt
  • WebRTC 之点对点连接——浏览器

    WebRTC 的精髓 点对点连接 上一篇文章中 主要讲了浏览器怎样获取用户设备上的视频流 并且显示在 HTML5
  • java以base64文件格式导出excel表格

    在项目中要求查询数据库并且用base64文件流的格式返回excel表格 自己试了好几种方法 最后找到的答案 错误方式 用HSSFWorkbook直接生成相对应的文件 然后用base64转化 这种解析出来的文件是打不开的 String enc
  • 上海万应云——大数据精准招商系统

    上海万应云数字科技有限公司 基于全国企业大数据与企业特有的经营数据 进行动态分析与整合 形成如下几个业务领域 1 针对地方政府 产业园 形成产业政策分析 产业链路图谱 区域经济报告 高潜企业挖掘 全面把握当地的产业经济状况 投融资实际落地情
  • [JAVA]将Set转换成int[]数组

    今天在写练习的时候 碰到了方法的返回值为int 可我却使用的是HashSet来实现 想return发现类型对不上的问题 于是尝试了toArray方法 但toArray方法返回的是Object类或者是一个包装类 就找到了这个set转换成int
  • 动态一键换肤实现思路和demo

    前言 浏览器切换样式无非是通过css 总共有以下三种方法 内联style 注入style 注入link 那么我们想要实现一键换肤 那么我们为了剥离干净dom和css 我们只能选择style和link这两种方法 核心思路 在html的head
  • Java反射机制和线程

    JAVA反射机制 已经加载过这个类 通过类名来找到这个类的所有相关信息 在运行时判断任意一个对象所属的类 在运行时构造任意一个类的对象 在运行时判断任意一个类所具有的成员变量和方法 在运行时调用任意一个对象的成员变量和方法 生成动态代理 反