目录
线程的生命周期
1.线程的创建启动 start()
2.线程可运行状态 抢占 等待cpu
3.线程运行状态 抢占 和执行
4.线程的阻塞 wait sleep 锁
5.线程的消亡 destroy
join方法
作用:让父线程等待,一直等到子线程结束以后,父线程才会执行。
package com.yhs.text;
class A implements Runnable {//子线程
@Override
public void run() {
for (int i = 0; i <100 ; i++) {
System.out.println(Thread.currentThread().getName()+":" + i);
}
}
}
public class Demo1 {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new A(),"子线程");
thread.start();//启动线程
thread.join();//需要抛一个异常;主线程等待,子线程先执行
for (int i = 0; i <100 ; i++) {
System.out.println("主线程:"+i);
}
}
}
生产者消费者模式
package com.yhs.text;
class Goods {//商品类
private String name;//商品的名字
private double price;//商品的价格
private boolean isProduct;//商品是否需要生产
//提供一个有参构造
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public boolean isProduct() {
return isProduct;
}
public void setProduct(boolean product) {
isProduct = product;
}
public Goods(String name, double price, boolean isProduct) {
this.name = name;
this.price = price;
this.isProduct = isProduct;
//set和get方法
}
}
class Customer implements Runnable {//消费者线程
private Goods goods;
public Customer(Goods goods) {
this.goods = goods;
}
@Override
public void run() {
while (true) {
//需要一直消费 判断商品是否有无
// //true需要生产 false 不需要生产
synchronized (goods) {
if (!goods.isProduct()) {
System.out.println("消费者购买:"+goods.getName() + ",价格为:"+goods.getPrice());
goods.setProduct(true);//购买完以后,商品没了,标记为true
goods.notify();//唤醒生产者让他生产
} else {
try {
goods.wait();//这里要try,catch;等待方法,需要生产消费者线程等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
class Productor implements Runnable {//生产者线程
private Goods goods;
public Productor(Goods goods) {
this.goods = goods;
}
@Override
public void run() {
int count = 0;
while (true) {
try {
Thread.sleep(2000);//需要trycatch,让线程睡2秒;
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (goods) {
if (goods.isProduct()) {
if (count % 2 == 0) {
goods.setName("迈巴赫");
goods.setPrice(99.9);
} else {
goods.setName("法拉利");
goods.setPrice(88.8);
}
goods.setProduct(false);
System.out.println("生产者生产了:"+ goods.getName()+ ",价格为:"+goods.getPrice());
count++;
goods.notify();//唤醒消费者
} else {
try {
goods.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
public class Demo2 {
public static void main(String[] args) {
Goods goods = new Goods("大牛", 55.5, false);
Customer customer = new Customer(goods);
Productor productor = new Productor(goods);
new Thread(customer).start();
new Thread(productor).start();
}
}
线程池
ThreadPoolExecutor
ThreadPoolExecutor 是最原始、也是最推荐的手动创建线程池的方式,它在创建时最多提供 7 个参数可供设置。ThreadPoolExecutor 使用示例如下:
import java.util.LinkedList;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Demo5 {
public static void main(String[] args) {
test();
}
public static void test () {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 100, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
//执行任务
for (int i = 0; i < 21; i++) {
int index = i;
threadPoolExecutor.execute(new Runnable() {
@Override
public void run() {
System.out.println(index + "被执行, 线程为:" + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
//threadPoolExecutor.shutdown();
}
}
}
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
反射
反射(Reflection) 被视为动态语言的关键。反射机制允许Java程序在运行过程中获取内部的信息
并能直接操作任意对象
反射可以换一种方式获取对象 对象的属性 对象的构造方法 对象的方法
Java虚拟机需要加载一个类,会变成.class文件(字节码文件)(存的是类的所有的信息)
Java可以通过反射将字节码文件变成一个对象。Class对象
package com.yhs.text;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Demo3 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class<Person> personClass = Person.class;
//将Person.class 这个文件变成成了 一个Class对象
System.out.println(personClass);//class com.yhs.text.Person
///将Person类的无参构造方法变成一个对象 Constructor
Constructor<Person> constructor = personClass.getConstructor(null);//这里要抛异常
Person person = constructor.newInstance();//这里需要抛异常
/**
* 1.获取字节码文件对象()
* 2.通过字节码文件获取构造方法对象
* 3.再通过构造方法对象创建Person对象
*/
Person person1 = new Person();
}
}
获取Class对象
Java文件的 Person.class文件 Java可以将他转换成Class对象
有三种:
package com.yhs.text;
public class Demo4 {
public static void main(String[] args) throws ClassNotFoundException {
//1.类.class获取
Class<Person> personClass = Person.class;
System.out.println(personClass);//class com.yhs.text.Person
//2..Class.forName 通过类的全限定名字来获取类所对应的CLass对象
Class<?> aClass = Class.forName("com.yhs.text.Person");//抛一个类找不到的异常
System.out.println(aClass);//class com.yhs.text.Person
//3. 通过对象来创建Class对象
Class<? extends Person> aClass1 = new Person().getClass();
System.out.println(aClass1);//class com.yhs.text.Person
}
}
获取Constructor对象
通过Class对象调用方法获取构造方法
Constructor<?>[]
getConstructors()
返回包含一个数组Constructor
对象反射由此表示的类的所有公共构造 方法Constructor<?>[]
getDeclaredConstructors()
返回一个反映Constructor
对象表示的类声明的所有Constructor
对象的数组类
。Constructor<T>
getConstructor(类<?>... parameterTypes)
返回一个Constructor
对象,该对象反映Constructor
对象表示的类的指定的公共类
函数。Constructor<T>
getDeclaredConstructor(类<?>... parameterTypes)
返回一个Constructor
对象,该对象反映Constructor
对象表示的类或接口的指定类
函数。
以上是Class对象调用的方法
以下是Constructor调用的方法
newInstance(Object... initargs)
使用此Constructor
对象表示的构造函数,使用指定的初始化参数来创建和初始化构造函数的声明类的新实例。
package com.yhs.text;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Demo5 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//获取person.class所对应的class对象
Class<Person> personClass = Person.class;
//获取公开的构造方法
Constructor<?>[] constructors = personClass.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
System.out.println("====================================");
//获取所有的构造方法
Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
}
System.out.println("========================================");
//获取指定的公开的无参构造方法
Constructor<Person> constructor = personClass.getConstructor(null);//需要抛异常
System.out.println(constructor);
//获取指定的公开的构造方法
Constructor<Person> constructor1 = personClass.getConstructor(String.class);
System.out.println(constructor1);
System.out.println("=====================");
//获取指定的构造方法包括私有的,默认的
Constructor<Person> declaredConstructor = personClass.getDeclaredConstructor();
System.out.println(declaredConstructor);
Constructor<Person> declaredConstructor1 = personClass.getDeclaredConstructor(int.class);
System.out.println(declaredConstructor1);
Constructor<Person> declaredConstructor2 = personClass.getDeclaredConstructor(double.class);
System.out.println(declaredConstructor2);
//借助于无参的构造出来一个对象 //这里要抛异常
Person person = declaredConstructor.newInstance(null);
// newInstance(Object ... initargs) 对构造方法进行赋值的
Person person1 = constructor1.newInstance("高渐离");
System.out.println(person1.name);
}
}
获取Method对象
方法[]
getMethods()
返回包含一个数组方法
对象反射由此表示的类或接口的所有公共方法类
对象,包括那些由类或接口和那些从超类和超接口继承的声明。方法[]
getDeclaredMethods()
返回包含一个数组方法
对象反射的类或接口的所有声明的方法,通过此表示类
对象,包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法。方法
getMethod(String name, 类<?>... parameterTypes)
返回一个方法
对象,它反映此表示的类或接口的指定公共成员方法类
对象。方法
getDeclaredMethod(String name, 类<?>... parameterTypes)
返回一个方法
对象,它反映此表示的类或接口的指定声明的方法类
对象。
以上方法都是Class对象调用的
以下方法是Method对象调用
Object invoke(Object obj, Object ...args);
使用方法对象调用invoke 方法会执行的
package com.yhs.text;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Demo6 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//获取Class对象
Class<Dog> dogClass = Dog.class;
//2.通过class对象获取下面的方法对象
//获取所有的公开的方法和父类公开的方法
Method[] methods = dogClass.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("==================");
//获取所有的方法
Method[] declaredMethods = dogClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
System.out.println("============================");
Method run = dogClass.getMethod("run", null);
System.out.println(run);
//获取私有化的方法
Method eat = dogClass.getDeclaredMethod("eat", String.class);
System.out.println(eat);
Dog dog = dogClass.getConstructor(null).newInstance(null);
run.invoke(dog,null);
eat.setAccessible(true);
eat.invoke(dog,"哈哈");
}
}
获取Field对象
Field[]
getFields()
返回包含一个数组Field
对象反射由此表示的类或接口的所有可访问的公共字段(属性)类
对象。Field[]
getDeclaredFields()
返回的数组Field
对象反映此表示的类或接口声明的所有字段类
对象。Field
getField(String name)
返回一个Field
对象,它反映此表示的类或接口的指定公共成员字段类
对象。Field
getDeclaredField(String name)
返回一个Field
对象,它反映此表示的类或接口的指定已声明字段类
对象。
以上的方法是Class对象
以下是Field对象的方法
package com.yhs.text;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class Demo7 {
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//1.获取person.class所对应的Class对象
Class<Cat> catClass = Cat.class;
//获取所有的公开的属性
Field[] fields = catClass.getFields();
for (Field field : fields) {
System.out.println(field);//public java.lang.String com.yhs.text.Cat.name
}
System.out.println("=====================");
//获取所有的属性对象
Field[] declaredFields = catClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
//public java.lang.String com.yhs.text.Cat.name
//private int com.yhs.text.Cat.age
//double com.yhs.text.Cat.weight
}
System.out.println("===============");
//获取单个属性
Field name = catClass.getField("name");
System.out.println(name);//public java.lang.String com.yhs.text.Cat.name
//获取单个私有或默认的属性
Field age = catClass.getDeclaredField("age");
System.out.println(age);//private int com.yhs.text.Cat.age
Cat cat = catClass.getConstructor(null).newInstance(null);//要抛两个异常
name.set(cat,"毛毛");
System.out.println(name.get(cat));//毛毛
age.setAccessible(true);
age.set(cat,5);
System.out.println(age.get(cat));//5
}
}