java基础-----第三关

文件操作

查看文件

public class 查看文件 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入文件夹");
		String next = scanner.nextLine();
		File file = new File(next);
		getall(file,0);
	}
	private static void getall(File file,int level) {
		for (int i = 0; i < level; i++) {
			System.out.print("\t");
		}
		System.out.println(file.getName());
		if(file.isDirectory()) {
			File[] files = file.listFiles();
			for (File f : files) {
				getall(f,level+1);
			}
		} 
	}
}

复制文件

public class 复制文件夹 {
	public static void main(String[] args) throws Exception {
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入源文件");
		String src = scanner.next();
		System.out.println("请输入目标");
		String dest = scanner.next();
		File file = new File(src);
		File file2 = new File(dest,file.getName());
		getall(file, file2);
	}

	private static void getall(File src, File dest) throws FileNotFoundException, IOException {
		if (!dest.exists()) {
			dest.mkdirs();
		}
		File[] listFiles = src.listFiles();
		if (listFiles!=null) {
			for (File f : listFiles) {
				if (f.isFile()) {
					BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(f));
					BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(new File(dest,f.getName())));
					int len = 0;
					byte[] by = new byte[1024];
					while((len = inputStream.read(by))!=-1){
						outputStream.write(by, 0, len);
					}
					outputStream.close();
					inputStream.close();
				}else {
					getall(f, new File(dest,f.getName()));
				}
			}
		}
	}
}

删除文件

public class 删除文件夹 {
	public static void main(String[] args) {
		Scanner scanner= new Scanner(System.in);
		String nextLine = scanner.nextLine();
		File file = new File(nextLine);
		delect(file);
		System.out.println("删除成功");
	}

	private static void delect(File file) {
		File[] listFiles = file.listFiles();
		if (listFiles!=null) {
			for (File f : listFiles) {
				if (f.isFile()) {
					f.delete();
				}else{
					if (f.delete()) {
						f.delete();
					}else {
						delect(f);
						f.delete();
					}
				}
			}
		}
	}
}

IO流

在这里插入图片描述
总结
1.输入流是从外部文件输入到内存;输出流是内存到文件
2.程序中的输入输出都是以流的形式保存的,流中保存的实际上都是字节文件
3.阻塞方法是指在程序调用该方法时,必须等待输入数据可用或者检测到输入结束或者抛出异常,否则程序会一直停留在该语句上,不会执行下面的语句。
4.流的底层都是字节。字符流是字节流的包装,方便直接接受字符串,它内部也是转成字节,写入底层。
5.尽量使用Buffered带有缓冲的类

多线程

java中使用的是抢占式调度
实现多线程编程的方式
1.继承Thread类:不能多继承。

public class Demo extends Thread{
	
	@Override
	public void run() {
		//重写run方法
		super.run();
	}
	
	public static void main(String[] args) {
		Demo demo = new Demo();
		//开启线程,让线程开始执行,让jvm调用run方法
		demo.start();
	}
}

2.实现Runnable接口:可能多实现。

public class Demo {
	
	public static void main(String[] args){
		
		MyThread myThread = new MyThread();
		Thread thread = new Thread(myThread);
		thread.start();
	}
}

class MyThread implements Runnable{
	@Override
	public void run() {
		// TODO Auto-generated method stub
	}
}

在线程类中,实例变量有共享与不共享之分。三个线程同时方法一个共享变量就会出现线程安全问题。
使用synchronized 同步关键字,让线程排队执行run方法。

@Override
	synchronized public void run() {
		// TODO Auto-generated method stub
	}

sleep()与wait()的区别
当一个Synchronized方法中调用sleep(),此时线程休眠,对象锁机制不会被释放,其他线程无法访问这个对象。进入就绪状态需要自己抢占cpu。
调用wait(),休眠对象,也会释放锁机制,其他线程可以访问该对象。
wait()方法和notify()方法
执行wait()后,休眠并释放锁机制,进入到与这个对象相关的等待池中。
被notify()唤醒时,等待池中的线程就被放到锁池中,线程获得锁,就会回到wait的中断地方。
wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用

线程池

线程池就是一个拥有多个线程的容器,其中的线程可以反复使用,减少了频繁创建线程、销毁线程的操作,减少资源消耗。
线程池优点

  1. 提高效率,创建好放入线程池中,使用直接拿,比创建快
  2. 方便管理,可以对线程池中线程统一管理

Exectutor顶级抽象类,是一个工厂类
****** ** ThreadPoolExecutor**
************** ** SingleThreadPool**:单例线程池
************** ** FixedThreadPool**:固定数量的线程池
************** ** CachedThreadPool**:缓存线程池,小型程序使用
****** ** ScheduledThreadPoolExecutor**:定期执行任务
************** ** SingleScheduledThreadPool**:单例延迟线程池
************** ** ScheduledThreadPool**:定时线程池

Exectutor创建线程池,失去了线程池的灵活性,而且存在一定的隐患,存在资源耗尽的可能,有最大容量的限制,也存在内存溢出的风险。

线程池都有哪几种工作队列

  1. ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序
  2. LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列
  3. SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。
  4. PriorityBlockingQueue:一个具有优先级的无限阻塞队列。
    核心参数
    corePoolSize:核心池的大小。
    maximumPoolSize:线程池最大线程数
    keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止
    unit:参数keepAliveTime的时间单位
    workQueue:一个阻塞队列,用来存储等待执行的任务
    threadFactory:用于设置创建线程的工厂
    handler:表示当拒绝处理任务时的策略

高并发

  1. 使用sychronized关键字,但是会十分影响效率
  2. 乐观锁,读不会冲突,写会冲突。读远大于写的场景
  3. 对同一个账号限制一次请求
  4. 对同一ip限制一次请求
  5. 前多少存进缓存服务器,后面请求等待。

产生死锁四个条件
互斥
占有且等待
不可抢占
循环等待

乐观锁VS悲观锁
悲观锁:自己在使用数据的时候一定有别的线程来修改数据,因此获取数据时候先加锁,确保数据不会被别的线程修改。synchronized关键字和Lock的实现类都是悲观锁。
乐观锁:自己在使用数据的时候不会有别的线程修改数据,所以不会加锁,只在更新数据的时候去判断之前有没有线程更新了这个数据。数据没有更改,写入成功;数据被修改,执行不同操作。最常用的CAS算法。

独享锁/共享锁
独享锁:该锁一次只能被一个线程持有
共享锁:该锁可被多个线程持有
ReentrantLock、Synchronized是独享锁。
ReadWriteLock读是共享锁、写是独享锁

可重入锁
递归锁:指在同一个线程在外层方法获取锁定时候,进入内层方法会自动获取锁。ReetrantLock、Synchronized都是可重入锁。

公平锁/非公平锁
公平锁是指多个线程按照申请锁的顺序来获取锁。
非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁。有可能,会造成优先级反转或者饥饿现象。ReetrantLock、Synchronized都是非公平锁。

偏向锁、轻量级锁、重量级锁、自旋锁的概念
偏向锁:如果一个线程获得了锁,那么锁就进入了偏向模式。当这个线程再次请求锁时,无需再做任何同步操作。
轻量级锁:简单的将对象头部作为指针,指向持有锁的线程堆栈的内部,来判断一个线程是否持有对象锁。
重量级锁:指当锁为轻量级锁的时候,另一个线程虽然是自旋,但自旋不会一直持续下去,当自旋一定次数的时候,还没有获取到锁,就会进入阻塞,该锁膨胀为重量级锁。重量级锁会让他申请的线程进入阻塞,性能降低
自旋锁:轻量级锁就会膨胀为重量级锁后,虚拟机为了避免线程真实的在操作系统层面挂起,虚拟机还会在做最后的努力

JVM

在这里插入图片描述
类加载机制
加载:类加载器获二进制字节流,将静态存储结构转化为方法区的运行时数据结构,并生成此类的Class对象。
验证:验证文件格式、元数据、字节码、符号引用,确保Class的字节流中包含的信息符合当前虚拟机的要求。
准备:为类变量分配内存并设置其初始值,这些变量使用的内存都将在方法区中进行分配。
解析:将常量池内的符号引用替换为直接引用,包括类或接口的解析、字段解析、类方法解析、接口方法解析。
初始化:执行类中定义的Java程序代码(字节码)。

java回收机制
程序中主动调用System.gc()强制执行的GC为full GC;
强引用:默认情况下,对象采用的均为强引用;
软引用:适用于缓存场景(只有在内存不够用的情况下才会被回收)
弱引用:在GC时一定会被GC回收
虚引用:用于判断对象是否被GC

新特性

java7新特性

  1. Switch中使用String
  2. try-with-resources(1.7以前对文件流等操作需要手动释放资源,7以后可以自动释放资源)
  3. 捕获多个异常,使用 | 隔开
	try {
              result = field.get(obj);
          } catch (IllegalArgumentException | IllegalAccessException e) {
              e.printStackTrace();
          }
  1. 泛型实例化类型自动推断
 	List<String> list = new ArrayList<>();
  1. 增加二进制表示
  2. 数字中可添加分隔符,可以出现 _ 作为分隔符
	int intOne = 1_000_000;
   long longOne = 1_000_000;
   double doubleOne = 1_000_000;
   float floatOne = 1_000_000;

java8新特性

  1. 接口的默认方法
    允许我们给接口添加一个非抽象的方法实现,只需要使用default关键字
interface Formula {
   double calculate(int a);
   default double sqrt(int a) {
       return Math.sqrt(a);
   }
}
  1. Lambda 表达式
    提高了阅读性
List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
Collections.sort(names, new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        return b.compareTo(a);
    }
});

Collections.sort(names, (String a, String b) -> {
    return b.compareTo(a);
});

Collections.sort(names, (String a, String b) -> b.compareTo(a));

Collections.sort(names, (a, b) -> b.compareTo(a));
  1. 函数式接口
    有且仅有一个抽象方法的接口,适用于Lambda使用的接口。使用@FunctionalInterface注解
  2. 方法与构造函数引用
    在这里插入图片描述
  3. Lambda 作用域
    访问局部变量:可以直接在lambda表达式中访问外层的局部变量。不允许声明一个与局部变量同名的参数或者变量。被引用的变量的值不可修改。
final int num = 1;
Converter<Integer, String> s =
        (param) -> String.valueOf(param + num);
 
s.convert(2);     // 3
public void repeat(String string, int count) {
        Runnable runnable = () -> {
            for (int i = 0; i < count; i++) {
                string = string + "a";//编译出错
                System.out.println(this.toString());
            }
        };
        new Thread(runnable).start();
}
	访问对象字段与静态变量:Lambda内部对于实例的字段(即:成员变量)以及静态变量是即可读又可写。
class LambdaDemo {
    static int myStaticNum;
    int myNum;
 
    void testScopes() {
        Converter<Integer, String> s1 = (param) -> {
            myNum = 33;
            return String.valueOf(param);
        };
 
        Converter<Integer, String> s2 = (param) -> {
            myStaticNum = 87;
            return String.valueOf(param);
        };
    }
}
	访问接口的默认方法:无法访问到默认方法的
  1. Date API
  2. Annotation 注解
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值