多线程
什么是线程
进程:当前正在运行的程序,一个应用程序在内存中的执行区域,也称为主线程。
线程:进程中的一个执行控制单元,执行路径
一个进程可以有一个线程,也可以有多个线程
单线程:安全性高,但是效率低
多线程:安全性低,但是效率高
线程与进程之间的关系
线程依托于进程
一个进程可以存在多个线程
单线程与多线程的区别:安全性,效率
开启线程几种方式
多线程得实现方式一:
Thread:
一种方法是将类声明为 Thread 的子类。
该子类应重写 Thread 类的 run 方法。
接下来可以分配并启动该子类的实例。
String getName():获取线程名字
void setName():改变线程名称
run():自己去重写的逻辑
start():开启线程
sleep(int time)单位为毫秒
多线程的实现方式二:
Runnable:
创建线程的另一种方法是声明实现 Runnable 接口的类。该类然后实现 run 方法。
然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。
主方法中代码的执行是多线程吗?
不是,主方法是单线程。
区别
Runnable和Thread的区别:
同步锁(慎用):
同步方法:
使用关键字synchronized所修饰。
注意:非静态同步方法的锁对象是this
静态同步方法的锁对象是当前类的字节码对象
同步方法代码块:
synchronizde:锁对象。同步,可以修饰代码块和方法,
被修饰的代码快和方法一旦被某个线程访问,则直接锁住,其他的线程将无法访问。
注意:锁对象要被所有的线程共享。
锁加在方法上和方法体里有什么区别?
加在方法上,外部一旦调用,就会卡在方法外等待上一个任务执行完成
加在方法体上,都会进入方法,只不过没办法进入加锁的逻辑中
使用同步锁的特点:
安全性提高,效率变低。
线程安全问题:
多个线程同时操作一个对象。使用同步锁解决问题。
线程池:
ThreadPoolExecutor
如何使用
使用线程池执行任务
execute(runnable对象)
移除任务
removed
反射
在运行时,我们可以获取任意一个类的所有方法和属性
在运行时,让我们调用任意一个对象的所有方法和属性
反射的前提:
获取类的对象(Class对象)
1.通过Object的getClass()方法获取,必须要有对象
2.通过类名获取字节码对象Object.class()
3.Class类中的静态方法
static Class<?> forName(String className)
通过反射获取构造方法并使用
Class:
Constructor<?>[] getConstructors():返回一个包含某些 Constructor 对象的数组,
这些对象反映此 Class 对象所表示的类的所有公共构造方法。
Constructor<T> getConstructor(Class<?>... parameterTypes) :返回一个 Constructor 对象,
它反映此 Class 对象所表示的类的指定公共构造方法。
T newInstance():便捷使用无参构造方法创建对象
Constructor:
T newInstance(Object...initargs):使用此 Constructor 对象表示的构造方法来创建该构造方
法的声明类的新实例,并用指定的初始化参数初始化该实例。
通过反射获取成员变量并使用:
Field getDeclaredField(String name)
Field[] getDeclaredFields():获取所有的成员变量
Field getField(String name):根据字段名称获取公共的成员变量
Field[] getFields():获取公共的成员变量
//获取学生类的字节码对象
//获取学生类的对象
Field
Object get(Object obj):返回指定对象上此 Field 表示的字段的值。
void set(Object obj, Object value):将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
通过反射获得私有成员变量并使用
Field[] getDeclaredFields():获取私有的字段对象
Field getDeclaredField(String name):根据字段名称获取私有的成员变量
Field的父类中的方法:
setAccessible(boolean b):设置反射时取消了Java的访问检查,暴力访问
通过反射获取成员方法并使用:
Method getMethod(String name,Class<?>...parameterTypes)
Method:
调用方法:
Object invoke(Object obj,Object...args):
javaBean
概念:用于封装数据
java类:
类使用公共进行修饰
提供私有的成员变量
为成员变量提供公共的get/set方法
提供公共的无参构造
实现序列化接口:(之前在对象读入输出流学过)
BeanUtils:
Apache commons提供的一个组件,主要功能就是为了简化JavaBean封装数据的操作
jar包:
static void setProperty(Object bean,Sting name,Object value):给JavaBean对象的成员变量进行赋值
static String getProperty(Object bean,String name):获取JavaBean对象的成员变量
注意:BeanUtils的setProperty和getProperty底层并不是直接操作成员变量,而是操作和变量有关的set/get方法
static void populate(Object bean,Map properties)
自定义BeanUtils:
public static void setProperty(Object bean,String name,Object value){}
步骤:
1.获取字节码对象
2.根据字段名称获取Field对象
3.调用set方法修改值
public static String getProperty(Object bean,String name):
步骤:
1.获取字节码对象
2.根据字段名称获取Field对象
3.调用get方法获取值
4.转字符串返回
public static void populate(Object bean,String name,Object name):
步骤:
1.获取字节码对象
2.根据字段名称获取Field对象
3.创建Map对象
4.获取所有的key(keySet)
5.遍历set集合,将key做为字段名称获取Field对象
6.调用set方法修改成员
注意:调用此方法时如果添加一个javaBean没有的字段,会报一个NoSuchFieldException异常,需要try-catch捕获异常
|
|