多线程和反射

多线程和反射

1. 多线程编程
1.1 什么是进程
	就是在计算机中运行的独立程序,例如:QQ 微信 网易云。这些程序是直接申请系统资源,系统资源包括: CPU使用率 内存占用率 硬盘,网络和显卡。
	进程:
		1. 互斥!!!
		2. 独立!!!
1.2 什么是线程
	线程就是进程中一部分,也可以认为是进程的一个功能模块。例如 电脑管家 可以同时执行 杀毒 清理 一键加速 体检。
	线程使用的资源是当前进程中分配的资源。每一个线程之间存在【共享资源】。同时在软件开发中,所有的线程都是【抢占式运行】。CPU执行线程会存在一个【单位时间片】概念。
	windows操作系统被称之多任务操作系统。只不过是在单位时间内,不同的软件直接进行跳转执行,单位时间足够短!!!
1.3 线程和进程的关系
	一个进程最少有一个线程!!!如果进程中没有任何一个线程存在,当前进程退出!!!线程分两大类 前台线程和守护线程。
【面试题】
	Java程序中最少有几个线程???
		任何一个Java程序最少两个线程
			一个main主线程,不是main方法!!!
			一个GC线程,Garbage Collection JVM的垃圾回收机制。
1.4 多线程的优缺点
中国的古话:
	物极必反!!!

优点:
	1. 可以提高资源利用率
	2. 可以增加用户体验
	
缺点:
	1. 增加了系统资源压力
	2. 降低了用户体验,多线程情况下,会导致卡顿问题。
	3. 容易导致死锁!!!
	4. 会导致共享资源冲突问题。
1.5 Java中自定义线程类的两种方式
1. 继承Thread类 
	Thread类是Java中所有线程的基类,Thread类配套线程操作方法

2. 遵从Runnable接口
	实现Runnable接口中方法run方法
package com.qfedu.a_thread;

/*

 * 遵从Thread类
 * 需要完成一个自定义线程类,必须重写run方法!!!
 * 
 * run 决定当前线程运行的核心代码是什么 What will be run? 跑啥~~~
   */
   class MyThread1 extends Thread {
   @Override
   public void run() {
   	for (int i = 0; i < 100; i++) {
   		System.out.println("继承Thread类,自定义线程对象");
   	}
   }
   }

/*

 * 遵从Runnable接口
 * 强制实现run方法
   */
   class MyThread2 implements Runnable {
   @Override
   public void run() {
   	for (int i = 0; i < 100; i++) {
   		System.out.println("遵从Runnable接口,实现自定义线程");
   		}
  	  }
   }

public class Demo1 {
	public static void main(String[] args) {
		// 继承Thread类线程对象启动
		MyThread1 mt1 = new MyThread1();
		// start方法用于线程启动!!!
		mt1.start();
        
        // 遵从Runnable接口实现类自定义线程对象启动
	Thread mt2 = new Thread(new MyThread2());
	
	mt2.start();
	
	for (int i = 0; i < 100; i++) {
		System.out.println("main方法线程.......");
		}
	}
}
1.6 多线程涉及到的方法
构造方法:
	Thread();
		创建一个啥也没有线程对象,没有执行目标和线程自有名称。
	Thread(Runnable target);
		提供给当前线程对象一个执行目标,参数是Runnable接口实现类对象,线程名称是
		系统默认的线程名称
	Thread(Runnable target, String threadName);
		提供给当前线程对象一个执行目标,同时赋予对应的线程名。
成员方法:
	void setName(String name);
		设置当前线程的名字
	String getName();
		获取当前线程的名字
	void setPriority(int newPriority);
		设置当前线程的优先级~~~优先级有范围约束 1 ~ 10 10最大 1最小 5默认
		优先级只能决定当前线程的执行概率,不保证执行顺序。
	int getPriority();	
		获取当前线程的优先级
	
	static Thread currentThread();
		在哪一个线程代码中执行,获取当前线程对象。
	static void sleep(int ms) throws InterruptedException
		在哪一个线程中执行,当前线程休眠对应的毫秒数
1.7 线程同步问题【重点】
1.7.1 多线程实际问题分析
<<金刚川>> 二七万达 IMAX 100张
销售渠道:
	淘票票 猫眼 美团
	三个销售线程 ==> 100张票是一个共享资源!!!

销售线程代码
共享资源处理
1.7.2 多线程共享资源问题分析
100张票需要保存的变量特征:
	1. 共享性
	2. 持久性

变量:
	成员变量
		持久性,独立性
	局部变量
		啥也不是~~~
	静态成员变量
		共享性,持久性

权限修饰符:
	私有 private修饰,不能对外公开使用,可以提供给用户一个查看消息的方法。
	公开

class SaleThread implements Runnable {
	@Override
	public void run() {
		// 线程销售代码
	}
}

main() {
	new Thread(new SaleThread(), "淘票票").start();
	new Thread(new SaleThread(), "猫眼").start();
	new Thread(new SaleThread(), "美团").start();
}
1.7.3 多线程共享代码部分使用和问题

在这里插入图片描述

1.7.4 同步代码块加锁
	同步代码块中,有且只允许一个线程对象执行,进入同步代码块,自动落锁,线程执行完毕,超出同步代码块范围以内,自动开锁。
格式:
	synchronized (锁·对象) {
				
	}
	1. 锁对象可以是任意对象!!!
	2. 同步代码块中有且只能运行一个线程执行。
	3. 在需要进行同步限制的线程中,锁对象必须是惟一的。
package com.qfedu.a_thread;

/*
 * 售票线程
 */
class SaleThread implements Runnable {
	private static int tickets = 1000;

	@Override
	public void run() {
		while (true) {
			synchronized ("锁") {
				if (tickets > 0) {
					System.out.println(Thread.currentThread().getName() + "售出了" + tickets + "张票");
					tickets--;
				} else {
					System.out.println(Thread.currentThread().getName() + ": 没票了,铁汁");
					break;
				}
			}
		}
	}
}

public class Demo3 {
	public static void main(String[] args) {
		Thread t1 = new Thread(new SaleThread(), "淘票票");
		Thread t2 = new Thread(new SaleThread(), "猫眼");
		Thread t3 = new Thread(new SaleThread(), "美团");

		t1.start();
		t2.start();
		t3.start();

	}
}
2. 反射 【重点】
2.1 Java中定义类的格式
class 类名 {
	成员变量 Field
	构造方法 Constructor
	成员方法 Method
}

类名 ==> 对于整个大括号以内的内容封装
整个class是包含当前数据类型的所有内容,当前数据类型的名字是类名 Class
2.2 Java文件和class的关系
Java文件就是.java结尾的一个文件,保存对应class的所有内容
2.3. .class字节码文件和Java文件的关系
	.class字节码文件 ==> Java文件通过 javac Java编译器编译之后得到的可以提供给JVM执行的二进制文件。
	.class文件中是否包含整个Java内容??? 是的
	.class文件中包含整个class对应的所有内容??? 是的
2.4 类文件(.class)加载过程,内存分析

在这里插入图片描述

2.5 万恶之源 Class对象
	Java中把.class字节码文件占用的【方法区】内存空间,看作是一个对象。Class类对象。
	
妙~十遍

Class Class.forName(String packageNameAndClassName);
	根据指定的完整包名.类名获取对应的Class对象。存在异常抛出 
	ClassNotFoundException
Class 类对象.getClass();
	通过类对象获取当前类对象对应的Class对象。
Class 类名.class;
	通过类名获取class属性。
package com.qfedu.b_reflect;

/*
 * 获取Class类对象
 */
public class GetClassObject {
	public static void main(String[] args) throws ClassNotFoundException {
		/*
		 * 通过完整的包名.类名获取对应的Class对象
		 */
		Class cls1 = Class.forName("com.qfedu.b_reflect.Person");
		
		/*
		 * 通过类对象获取Class对象
		 */
		Class<? extends Person> cls2 = new Person().getClass();
		
		/*
		 * 通过类名获取Class属性
		 */
		Class cls3 = Person.class;
		
		System.out.println(cls1);
		System.out.println(cls2);
		System.out.println(cls3);
		
		/*
		 * 不管通过哪一种方式获取的Class对象都是同一个对象
		 */
		System.out.println(cls1 == cls2);
		System.out.println(cls2 == cls3);
		System.out.println(cls3 == cls1);
	}
}
2.6 Constructor类对象获取
2.6.1 构造方法必要条件
构造方法
	一样: 方法名 ==> 类名
	不一样: 
		形式参数列表 参数列表,参数个数,参数顺序。
		权限修饰符 公开的或者私有的

如果想要获取一个构造方法:
	参数情况 【类型】
	权限修饰符
2.6.2 获取Constructor对象方法
Constructor[] getConstructors();
	通过Class对象调用,获取当前类内的所有非私有化构造方法对象数组
	
Constructor[] getDeclaredConstructors();
	【暴力反射】
	通过Class对象调用,获取当前类内的所有构造方法对象数组,包括私有化构造方法

Constructor getConstructor(Class... initParameterTypes);
	通过Class类对象调用,获取当前类内指定数据类型的非私有化构造方法类对象
	案例:
		无参数构造方法 public Person();
		cls.getConstructor();
		有参数构造方法 public Person(int, String);
		cls.getConstructor(int.class, String.class);
		类型.class来告知编译器,这里需要的数据类型是哪一个。

Constructor getDeclaredConstructor(Class... initParameterTypes);
	【暴力反射】
	通过Class类对象调用,获取当前类内指定的数据类型构造方法,包含私有化构造方法
	案例:
		String类型私有化构造方法 private Person(String);
		cls.getDeclaredConstructor(String.class);

Object newInstance(Object... initParameters);
	Object... 这里需要的参数是Object类型,个数不限,但是需要对应当前构造方法对象的参数列表顺序,个数和类型。
	Constructor con ==> public Person(int, String);
	Person p = (Person) con.newInstance(10, "苟磊");
package com.qfedu.b_reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class GetConstructorObject {
	public static void main(String[] args) 
			throws ClassNotFoundException, NoSuchMethodException, SecurityException, 
			InstantiationException, IllegalAccessException, IllegalArgumentException, 
			InvocationTargetException {
		/*
		 * 通过完整的包名.类名获取对应的Class对象
		 */
		Class cls1 = Class.forName("com.qfedu.b_reflect.Person");
		
		/*
		 * 所有非私有化构造方法
		 */
		Constructor[] constructors = cls1.getConstructors();
		for (Constructor constructor : constructors) {
			System.out.println(constructor);
		}
		
		System.out.println();
		/*
		 * 所有构造方法
		 */
		Constructor[] declaredConstructors = cls1.getDeclaredConstructors();
		for (Constructor constructor : declaredConstructors) {
			System.out.println(constructor);
		}
		
		System.out.println();
		/*
		 * 获取指定参数类型的非私有化构造方法
		 */
		Constructor con1 = cls1.getConstructor();
		Constructor con2 = cls1.getConstructor(int.class);
		Constructor con3 = cls1.getConstructor(int.class, String.class);
		
		System.out.println(con1);
		System.out.println(con2);
		System.out.println(con3);
		
		/*
		 * 获取类内私有化构造方法
		 */
		Constructor con4 = cls1.getDeclaredConstructor(String.class);
		System.out.println(con4);
		
		System.out.println();
		/*
		 * 创建对象
		 */
		Person p = (Person) Class
				.forName("com.qfedu.b_reflect.Person")
				.getConstructor(int.class, String.class)
				.newInstance(1, "苟磊");
		
		System.out.println(p);
		Person person = new Person(1, "苟磊");
		System.out.println(person);
		
		Person object = getObject(Person.class);
		System.out.println(object);
		
		/*
		 * 私有化构造方法对象调用
		 * 给予暴力反射操作权限
		 */
		con4.setAccessible(true);
		Object newInstance = con4.newInstance("测试");
		System.out.println(newInstance);
	}
	
	public static <T> T getObject(Class<T> cls) 
			throws InstantiationException, IllegalAccessException, IllegalArgumentException, 
			InvocationTargetException, NoSuchMethodException, SecurityException {
		return cls.getConstructor().newInstance();
	}
}
【补充知识点 给予暴力反射操作权限】
/*
 * 私有化构造方法对象调用
 * 给予暴力反射操作权限
 */
con4.setAccessible(true);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值