JAVASE23天从入门到精通_Day19

PrintStream/PrintWriter
PrintStream/PrintWriter : 打印字节流/打印字符流 -> 都是输出流

PrintStream : 是标准系统输出流对象的类型 -> System.out

PrintWriter: 打印字符流
	1. 兼容性很强
	2. 具备自动刷新和自动换行的能力
		自动刷新 : 打开自动刷新的开关并且输出时println(),printf(),format()之一
		自动换行 : 输出时必须使用 println() 方法
		
构造方法:
	PrintWriter(String fileName) 
        源码:
this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))),
             自动刷新开关: false);
	PrintWriter(File file) 
        
    //包装流在此体现    
    PrintWriter(Writer out)  
        源码: this(out,自动刷新开关: false);
    //转换流在此体现
    PrintWriter(OutputStream out)   
    
    //带自动刷新开关的两个构造在这里    
    PrintWriter(Writer out, boolean autoFlush) 
    PrintWriter(OutputStream out, boolean autoFlush)    
        
 写方法:
	1. 作为字符流 : 
		write() : 一次写一个字符,一次写一个字符数组,一次写一个字符数组的一部分,一次写一个字符串,一次写一个字符串的一部分
	2. 作为打印流 :
		print(任意类型的对象) :不带换行的输出方法 //注意print() 没有空参方法
        println(任意类型的对象) : 带换行的输出方法 //注意println() 有空参方法,空参方法就是在输出换行 
Properties(重点)
Properties : 属性集

注意事项:
	1. PropertiesHashtable的子类 -> 所以他是一个 双列集合 !!\
	2. 既然是双列集合就要满足双列集合的特点 : 键唯一,值可以重复,夫唱妇随
    3. Properties 集合创建时不可以给泛型(不能打尖括号)   //因为在创建Properties类时,把父类的泛型写死了 -> <Object,Object>
    4. 一般使用Properties集合都是和IO技术配合,要想和IO实现快捷交互必须要求Properties集合中键和值的元素类型都是 String !! **** 
    5. Properties具备全套双列集合的基本使用方法(put,keySet,entrySet)
        
Properties的特殊功能:
	替换put和set方法: Object setProperty(String key, String value) 
    替换keySet方法 : Set<String> stringPropertyNames()  -> 召集所有的丈夫
    替换get方法 : String getProperty(String key) 
Properties和IO交互的方法
一键加载:
	 void load(InputStream inStream) 
 	 void load(Reader reader) 

一键存储: comments: 文档注释
	 void store(OutputStream out, String comments) 
     void store(Writer writer, String comments)  
进程和线程
进程 : 正在运行的应用程序 -> 内存

线程 : 线程是存在于进程中的某个执行任务
	//线程必须存在于进程中
	//一个进程至少有一个线程
	//市面上绝对大部分进程都是多线程
	
CPU处理的是 线程! 
    	站在CPU角度: CPU在多个线程中进行切换!	(收集进程中所有的线程,进行告诉切换)
        站在线程角度: 多个线程同时抢夺CPU的执行权,谁抢到了谁执行
        
现在编写的代码 一个Java程序就是一个 进程!   //之前是单线程程序     
并行和并发
并发 : 在同一时间段,有多个事情同时发生 -> 同一时间段
并行 : 在同一时刻,有多个事情同时发生 -> 同一时刻

多线程的程序是并行还是并发的? 即是并行也是并发
线程的体系结构

在这里插入图片描述

线程开启方式
线程开启方式1 : 继承的方式
	1.准备类 继承Thread -> 自己的线程类
	2.主动重写run方法,编写线程的任务
	3.在使用线程的地方,创建自己线程类的线程对象
	4.启动线程 -> 调用start() -> 调用start才会开启新的栈
	
线程开启方式2: 实现的方式
	1. 准备类实现Runnable,必须重写run方法 -> 稍作修改
	2. 在使用线程的地方,创建任务对象和Thread对象
	3. 把任务对象分配给线程对象
		//线程的构造 : Thread(Runnable target)
	4. 线程对象调用start方法
	
线程开启方式3: 带有结果的线程任务
	RunnableFutureTask 父接口
	 Thread(Runnable target) 就可以接收 FutureTask 对象
	 FutureTask对象创建时可以接收 Callable<V> 实现类对象

	Callable<V> 线程任务接口 -> V call() --> 实现的方式
	中间媒介 : FutureTask<V> 
		构造:
			FutureTask(Callable<V> call) : 直接传入有结果的任务对象
            FutureTask(Runnable runnable, V result) : 传入无结果的任务对象,并手动给结果
     利用Thread的构造 :    Thread(Runnable target) 来接收FutureTask对象    
多线程程序的内存图

在这里插入图片描述

线程对象设置线程名称和获取线程名称
设置线程名称:
	1.Thread类中 成员方法: void setName(String name)
    2.Thread类中 构造方法: 
			Thread(String name) 
			Thread(Runnable target, String name) 
                
获取线程名称: 
	1. Thread 类中 成员方法 : String getName()
        如果不能直接调用getName方法,就需要先获取当先线程对象: 
				Thread类中 static Thread currentThread() 
线程对象的休眠方法
Thread类中:
	static void sleep(long millis)  : 让线程睡一下! -> 睡多久取决于long millis值
		//当线程被休眠,线程对象不会去抢夺CPU的执行权,放弃CPU资源,让其他线程执行
		
		当时间到,线程对象会自己醒来并且去抢夺CPU执行权
线程的优先级问题
线程的优先级 : [1-10]

线程最小的优先级 : 1
线程最大的优先级 : 10
线程默认的优先级 : 5 
    
优先级越高的线程,抢到CPU执行权的概率越高!! 
    
设置线程优先级的方法: Thread
	void setPriority(int newPriority) 
线程的守护线程问题
A线程如果守护着B线程,B线程死亡了,就算A线程没有执行完毕也会死亡(A线程有可能不是立刻死亡)
    
 void setDaemon(boolean on) : 如果一个线程被标记为守护线程,那么被他守护的线程执行完毕后,立即死亡(有可能不会立即死亡)    
线程安全问题
问题 : 多个线程操作共享数据,极有可能产生线程安全问题;

解决方案:
	1. 对需要保护的代码上锁!!一定能解决线程安全问题的! -> 弊端:效率低
解决方案 -> 上锁 -> 同步代码块
通过同步代码块,对需要保护的代码进行上锁

锁具备的特点:
	1. 锁必须被所有的线程对象共享 -> 这把锁可以管住所有的线程 -> 重要!!
    2. 锁可以是任意类型的对象,但是必须是引用数据类型  -> Object类型  
    
同步代码块的格式:
    synchronized(锁对象){
		//需要被保护的代码
    }

	如果多线程代码被同步操作 : 1. 抢夺CPU的执行权 2. 抢夺锁资源
	
	sleep 只会释放CPU的执行权,不会释放锁!! -> 抱着锁睡
解决方案 -> 上锁 -> 同步方法
通过同步方法,对需要保护的代码进行上锁


同步方法的格式:
    权限修饰符 synchronized 返回值类型 方法名(形参){
        方法体;//需要被保护的代码
    }

非静态的同步方法 的锁对象 : this
静态的同步方法 的锁对象 : 类的字节码对象    
解决方案 -> 上锁 -> 面向对象的锁
JDK提供了一个专门上锁的接口 : Lock
	接口中有2个抽象方法:
		void lock(): 上锁
		void unlock(): 解锁
		
具体使用的对象: ReentrantLock		
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值