Java回顾3【笔记】
1. 多线程
实现多线程的两种方式,注意,只有start()方法才是启动线程
一、创建一个类继承Thread类并重写run方法,创建该类的对象.start();启动线程
二、类实现Runnable重写run方法,将该类作为参数放在Thread类中.start();启动线程
例子:
new My().start();//My是我创建的类继承了Thread
Runnable r = () -> System.out.println("Runnable:" + Thread.currentThread());
new Thread(r).start();//启动Runnable的线程
System.out.println("Main:" + Thread.currentThread());//主方法的线程
输出结果:
Extends:Thread[Thread-0,5,main]
Main:Thread[main,5,main]
Runnable:Thread[Thread-1,5,main]
线程安全问题,需加锁:同步代码块、同步方法
同步代码块:synchronized(锁对象){}
锁对象的选择:可以是任意类型的对象,只要几个线程是用的同一个对象即可,this也行,自己创建一个静态对象也行
但是继承Thread的类创建多个线程不能用this,因为此时创建了好几个Thread对象,不是同一个
锁的范围:锁的范围很重要,具体问题具体分析
同步方法:public synchronized void test(){}
锁对象不是我们来选择的:
非静态方法:this(所以不适用继承)
静态方法:当前类的Class对象
死锁:博客里有
常用API:
Thread.sleep(500);//当前线程睡一会儿
Thread.currentThread();//获取当前线程对象
getName()//线程名称
interrupt():当某个线程在sleep的时候,将其敲醒,会触发异常
join():指代被哪个线程join,例如写在main方法中,是指xx.join(),main等xx执行完再执行,是main被阻塞了。
yield():暂停,直接回到就绪状态而不是阻塞,然后也会参加下一次调度
生产者与消费者问题
就是一个生产一个消费。当生产足够的时候就wait(),消费至0的时候也wait()
wait()之后一旦可以继续生产或者消费了就需要notify()唤醒。
如果你是消费者,notify()可能还是会唤醒消费者,这样就卡死了。所以需要用notifyAll(),全部唤醒
注意:这几个方法都必须由同步锁对象调用
只有wait()和join()方法会释放锁,join的底层是wait实现的。
2. 反射
//反射
//两种方式都能获取到
Class<?> oo = Class.forName("hello.Order");
Class<Order> o = Order.class;
//我只列举了这几个,从上往下从左往右的顺序排列
System.out.println("包名:" + oo.getPackage());
System.out.println("注解:" + o.getAnnotations().length);
//getDeclaredXXX() 与 getXXX()的区别
//getDeclaredXXX():private的可以获取到
//getXXX():继承的可以获取到
System.out.println("修饰符: 数字:" + o.getModifiers() + " 名字:" + Modifier.toString(o.getModifiers()));
System.out.println("类名:" + o.getName());
System.out.println("父类:" + o.getSuperclass());
System.out.println("接口:" + o.getInterfaces().length);
System.out.println("属性:" + o.getDeclaredFields().length);
System.out.println("构造器:" + o.getConstructors().length);
System.out.println("方法:" + o.getDeclaredMethods().length);
//后面有加length的都是数组对象,需要单独去遍历
//当然有很多方法都是有参的,也就是可以直接选定某个东西
//例如:o.getDeclaredField("id"),就直接拿到了id这个属性
//属性的类型 getType()
Field[] fields = o.getDeclaredFields();
System.out.println("属性的类型:" + fields[0].getType());
//构造器/方法的形参 getParameterTypes()
Constructor<?>[] constructors = o.getConstructors();
System.out.println("构造器形参:" + constructors[1].getParameterTypes().length);
//操作篇:
//创建对象
Order order = o.newInstance();//直接创建
Object o1 = o.getConstructors()[0].newInstance();//构造器创建
Object o2 = o.getConstructor(Integer.class).newInstance(2);//有参构造器创建
//给属性赋值(创建对象后的基础上)
Field id = o.getDeclaredField("id");
id.setAccessible(true);//private 也可以赋值
id.set(order, 5);
//调用方法(创建对象后的基础上)
Method setType = o.getDeclaredMethod("setType", String.class);//方法名, 形参列表
setType.invoke(order, "hello");
System.out.println("id:" + order.getId() + " type:" + order.getType());
3. IO
File类
//递归列出所有文件
public static void listAllSub(File dir){
if(dir.isDirectory()){// isDirectory()
File[] listFiles = dir.listFiles();// listFiles()
for(File f : listFiles){
listAllSub(f);
}
}
System.out.println(dir);
}
//递归获取文件大小
public static long getSize(File file){
if(file.isFile()){// isFile() 不用判断也行,和其他方法一样
return file.length();
}else if(file.isDirectory()){
long sum = 0;
File[] files = file.listFiles();
for(File f : files){
sum += getSize(f);
}
return sum;
}
return 0;
}
//递归删除
public static void deleteDir(File file){
if(file.isDirectory()){
File[] files = file.listFiles();
for(File f : files){
deleteDir(f);
}
}
file.delete();
}
public static void main(String[] args) {
File file = new File("D:\\LearningData\\Code\\GitTest\\recording");
listAllSub(file);
System.out.println(getSize(file));
//过滤器,接受
File[] filter = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().endsWith(".txt") && pathname.getName().contains("test");
}
});
for(File f : filter){
System.out.println(f);
}
}
超类:
InputStream/OutputStream/Reader/Writer
一般用用的:File~
缓冲:Buffered~
转换:InputStreamReader/OutputStreamWriter,其实相当于组合了一下
public static void main(String[] args) throws Exception {
FileReader fileReader = new FileReader("1.txt");
readFile(fileReader);
}
public static void readFile(FileReader fileReader) throws IOException {
char[] arr = new char[10];
int len;
while((len = fileReader.read(arr)) != -1){// read(char[] arr)将内容存在char[]中并且给长度,长度为-1则为空
System.out.print(new String(arr, 0, len));
}
fileReader.close();
}
FileWriter也new一个对象存放内容,然后在while循环里用write()方法将arr写进去
记住,当用到装饰者模式的时候,close()时要先脱外衣,再脱内衣,也就是将装饰的一层外衣先脱掉
FileInputStream/FileOutputStream用法与FileReader/FileWriter相同只是char[]要改为byte[],而且因为是byte可能会出现乱码,我在new String()后面加一个参数"utf-8"也不能很好解决
所以可以用InputStreamReader(fileInputStream,"utf-8"),装饰者模式,用这个对象的时候又得将byte改为char,其实就是变成Reader吧????
当然也有OutputStreamWriter(这两个应该最奇葩,是将超类组合了一下)
BufferdReader
public static void main(String[] args) throws Exception {
FileReader fileReader = new FileReader("1.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
buffReadFile(bufferedReader);
fileReader.close();
}
public static void buffReadFile(BufferedReader bufferedReader) throws IOException {
while(bufferedReader.ready()){// read()方法
System.out.println(bufferedReader.readLine());// readLine()读取整行
}
bufferedReader.close();
}
我原以为BufferdInputStream也有readLine()方法,就可以很容易的解决乱码问题,原来没有!
知识离开了脑子,就只是一堆文字

浙公网安备 33010602011771号