下载jdk地址
https://www.oracle.com/technetwork/java/javase/archive-139210.html
需要登录,选择对对应版本下载安装
windows环境变量配置
添加变量
JAVA_HOME=jdk安装路径
CLASSPATH=.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar
追加path变量
%JAVA_HOME%\bin
%JAVA_HOME%\jre\bin
线程池
实现Runnable接口、继承Thread类 创建线程方式
Executors 创建线程池工具类
newCachedThreadPool 缓存线程池
newFixedThreadPool 固定线程大小线程池
newSingleThreadExecutor 单线程线程池
newScheduledThreadPool 定时调度线程池
ThreadPoolExecutor 创建线程池类,参数如下
corePoolSize 核心线程数
maximumPoolSize 最大线程数
keepAliveTime 空闲时间
unit 空间时间单位
workQueue 任务队列
threadFactory 线程工厂
handler 线程拒绝策略(4)
AbortPolicy(异常终止,会抛异常,默认策略)
DiscardPolicy(丢弃新任务策略)
DiscardOldestPolicy(丢弃旧任务策略)
CallerRunsPolicy(主线程调用执行)
锁机制
synchronized(可重入锁、jvm实现) //同步关键字
volatile(禁止指令重排序、保证线程可见性)
//可见性:缓存一致性协议
//禁止指令重排序:JMM模型里有8个指令完成数据的读写,通过其中load和store指令相互组合成的4个内存屏障实现禁止指令重排序
ReentrantLock(可重入锁、api实现、lock()、unlock()) //重入锁
ReentrantReadWriteLock(读写锁、不限制读限制写、api实现、readLock()、writeLock())
ReentrantReadWriteLock.WriteLock(lock()、unlock())
ReentrantReadWriteLock.ReadLock(lock()、unlock())
AtomicInteger.cas //原子变量
wait、notify、notifyAll //线程的等待、通知机制
AQS (Template Method、AbstractQueuedSynchronizer)
CAS (Unsafe、ABA问题、加版本号、compareAndSet、compareAndSwap)
并发编程
CountDownLatch(N) countDown()、await() //门闩
N减为0后,释放await()
等待其他多个任务执行完成后在执行此任务
CyclicBarrier(N, r) await() //回环栅栏(可重用)
await调用N次后执行r方法后释放await()
所有任务都达到某个点后一起执行任务
Semaphore(N) acquire()、release() //信号量
对N个资源限制访问,看谁能获取到
ThreadLocal(set、get、数据存储在当前线程)
LockSupport(线程停止、唤醒、park()、unpark(thread))
IO流
InputStream、OutputStream //字节流基类
Reader、Writer //字符流基类
FileInputStream、FileOutputStream //处理字节文件
FileReader、FileWriter //处理字符文件
ByteArrayInputStream、ByteArrayOutputStream //处理字节数组
CharArrayReader、CharArrayWriter //处理字符数组
BufferedInputStream、BufferedOutputStream //字节缓存流
BufferedReader、BufferedWriter //字符缓存流
反射
//通过反射调用方法
Class cls = Class.forName("com.rbc.Student");
Object obj = cls.newInstance();
Method method = cls.getMethod("hello");
method.invoke(obj);
//获取字节码信息的四种形式(获取的字节码都会相等)
//方式1:通过getClass()方法获取
Person p = new Person();
Class c1 = p.getClass();
//方式2:通过内置class属性:
Class c2 = Person.class;
//方式3:--》用的最多:调用Class类提供的静态方法forName
Class c3 = Class.forName("com.zhaoss.test02.Person");
//方式4:利用类的加载器(了解技能点)
ClassLoader loader = Test.class.getClassLoader();
Class c4 = loader.loadClass("com.zhaoss.test02.Person");
//通过字节码信息可以获取构造器:
Constructor[] c1 = cls.getConstructors(); //只能获取当前运行时类的被public修饰的构造器
Constructor[] c2 = cls.getDeclaredConstructors();//获取运行时类的全部修饰符的构造器
Constructor con1 = cls.getConstructor(); 得到无参构造器
Constructor con2 = cls.getConstructor(double.class, double.class);//得到指定的两个参数的有参构造器:
Constructor con3 = cls.getDeclaredConstructor(int.class);//得到一个参数的有参构造器:并且是private修饰的
//构造器创建对象
Object o1 = con1.newInstance(); //无参构造器创建对象
Object o2 = con2.newInstance(180.5, 170.6);//指定参数构造器创建对象
//获取属性:
Field[] fields = cls.getFields();//获取运行时类和父类中被public修饰的属性
Field[] declaredFields = cls.getDeclaredFields();//获取运行时类中的所有属性
//获取指定名字的属性:
Field score = cls.getField("score");
Field sno = cls.getDeclaredField("sno");
//属性的具体结构:
//获取属性修饰符
String s = Modifier.toString(sno.getModifiers());
//获取属性的数据类型:
Class clazz = sno.getType();
String typeName = clazz.getName();
//获取属性的名字:
String name = sno.getName();
//给属性赋值:(给属性设置值,必须要有对象)
Field sco = cls.getField("score");
Object obj = cls.newInstance();
sco.set(obj,98);//给obj这个对象的score属性设置具体的值,这个值为98
//获取方法:
Method[] methods = cls.getMethods();//获取运行时类的方法还有所有父类中的方法(被public修饰)
Method[] declaredMethods = cls.getDeclaredMethods(); //获取运行时类中的所有方法:
//获取指定的方法:
Method showInfo1 = cls.getMethod("showInfo");
Method showInfo2 = cls.getMethod("showInfo", int.class, int.class);
Method work = cls.getDeclaredMethod("work",int.class);
//获取方法的具体结构:
//方法名字:
System.out.println(work.getName());
//修饰符:
int modifiers = work.getModifiers();
System.out.println(Modifier.toString(modifiers));
//返回值:
System.out.println(work.getReturnType());
//参数列表:
Class[] parameterTypes = work.getParameterTypes();
//获取注解:
Method myMethod = cls.getMethod("myMethod");
Annotation[] annotations = myMethod.getAnnotations();
//获取异常:
Class[] exceptionTypes = myMethod.getExceptionTypes();
//调用方法:
Object o = cls.newInstance();
myMethod.invoke(o);//调用o对象的mymethod方法
showInfo2.invoke(o,12,45)
//获取运行时类的接口:
Class[] interfaces = cls.getInterfaces();
//得到父类的接口:
//先得到父类的字节码信息:
Class superclass = cls.getSuperclass();
//得到接口:
Class[] interfaces1 = superclass.getInterfaces();
//获取运行时类所在的包:
Package aPackage = cls.getPackage();
System.out.println(aPackage);
System.out.println(aPackage.getName());
//获取运行类的注解:
Annotation[] annotations = cls.getAnnotations();
//【1】问题1:创建Person的对象,以后用new Person()创建,还是用反射创建?
正常使用new创建对象,仅在某些地方使用反射会比较方面的统一处理创建对象
//【2】问题2:反射是否破坏了面向对象的封装性?
虽然提供了反射,并不一定非要使用,仅在某些特定场合使用
RPC调用
//客户端
public static void main(String[] args) throws Exception {
//TCP的网络连接
Socket socket = new Socket("127.0.0.1",8888);
//发送请求
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
Class clazz = IUserService.class;
Method method = clazz.getMethod("findUserByID", Integer.class);
String methodName= method.getName();//方法
Class[] parametersTypes = method.getParameterTypes();//参数类型
Object[] params={1};
//格式(0: 类名 1:方法名、2、方法参数类型 3、参数值)
objectOutputStream.writeUTF(clazz.getName());
objectOutputStream.writeUTF(methodName);
objectOutputStream.writeObject(parametersTypes);
objectOutputStream.writeObject(params);
objectOutputStream.flush();
//处理响应
ObjectInputStream dataInputStream = new ObjectInputStream(socket.getInputStream());
Object o = dataInputStream.readObject();
//响应端 对象不就行了
objectOutputStream.close();
socket.close();
System.out.println(o);
}
//服务端
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8888);//监听8888端口
while (true){
Socket socket =serverSocket.accept();//网络请求过来了,使用socket通道(没有则阻塞)
//业务的处理
process(socket);
socket.close();//关闭
}
}
private static void process(Socket socket) throws Exception{
InputStream inputStream = socket.getInputStream();//客户端送过的信息
OutputStream outputStream= socket.getOutputStream();//响应客户端
ObjectInputStream dataInputStream = new ObjectInputStream(inputStream);
ObjectOutputStream dataOutputStream = new ObjectOutputStream(outputStream);
System.out.println("process");
//格式(0: 类名 1:方法名、2、方法参数类型 3、参数值)
String clazzName = dataInputStream.readUTF();
String methodName = dataInputStream.readUTF();
Class[] parametersTypes =(Class[]) dataInputStream.readObject();
Object[] args=(Object[]) dataInputStream.readObject();
//通过反射去调用
//这里一般会从服务的注册表中去找(RPC框架中, 服务的注册中心)
Class clazz = UserServiceImpl.class;
Method method = clazz.getMethod(methodName,parametersTypes);
User user = (User)method.invoke(clazz.newInstance(),args);//通过反射调用
dataOutputStream.writeObject(user);//这里就需要根据不同的类,
dataOutputStream.flush();//刷新缓冲区
}
版权声明:本文为rbcd原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。