转换流
含义
:字节流装成字符流
种类
- InputSteamReader - 
- 将字节输入流转为字符输入流 
 
- OutputStreamWriter - 
- 将字节输出流转为字符输出流 
 
案例一
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 
 | public class _01ByteInputToCharInput {
 public static void main(String[] args) {
 
 BufferedReader bufferedReader=null;
 try {
 
 InputStream inputStream = new FileInputStream("C:\\11.txt");
 
 
 InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
 
 bufferedReader = new BufferedReader(inputStreamReader);
 
 System.out.println(bufferedReader.readLine());
 
 } catch (IOException e) {
 e.printStackTrace();
 }finally {
 if(bufferedReader!=null){
 try {
 bufferedReader.close();
 } catch (IOException e) {
 
 e.printStackTrace();
 }
 }
 }
 
 }
 }
 
 | 
案例二
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 
 | public class _02ByteOutToCharOutput {
 public static void main(String[] args) {
 
 
 OutputStreamWriter outputStreamWriter=null;
 try {
 OutputStream outputStream = new FileOutputStream("C:\\22.txt",true);
 
 
 
 
 outputStreamWriter = new OutputStreamWriter(outputStream);
 
 outputStreamWriter.write("\r\n中国你好\r\n");
 outputStreamWriter.write("台湾你好\r\n");
 
 } catch (IOException e) {
 e.printStackTrace();
 }finally {
 if(outputStreamWriter!=null){
 try {
 outputStreamWriter.close();
 } catch (IOException e) {
 
 e.printStackTrace();
 }
 }
 }
 }
 }
 
 | 
序列化 & 反序列化
序列化
- 将对象转成二进制并保存到磁盘中 - 
- 对象需要实现序列化接口 
 
反序列化含义
- 将磁盘中的二进制对象加载到内存中 - 
- 对象需要实现序列化接口 
 
要求
- 包名序列化前后也要一样 
- 实现Serializable接口 
- 生成一个版本号 - 
- 作用:用来校验类是否修改过 
 
案例
User.java
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 
 | public class User implements Serializable{
 
 
 
 private static final long serialVersionUID = -3986195817302832270L;
 
 private String name;
 private Integer num;
 
 public User(String name, Integer num) {
 super();
 this.name = name;
 this.num = num;
 }
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public Integer getNum() {
 return num;
 }
 public void setNum(Integer num) {
 this.num = num;
 }
 @Override
 public String toString() {
 return "User [name=" + name + ", num=" + num + "]";
 }
 }
 
 | 
Test.java
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 
 | public class Test {
 public static void main(String[] args) {
 
 
 
 
 
 
 
 
 
 String target = "C:\\xx.txt";
 
 
 
 
 
 
 
 User result =  objectInput(target);
 System.out.println(result);
 }
 
 
 
 
 
 
 private static void objectOutput(String target,User user) {
 
 
 
 
 OutputStream outputStream=null;
 ObjectOutputStream objectOutputStream=null;
 try {
 outputStream = new FileOutputStream(target);
 objectOutputStream = new ObjectOutputStream(outputStream);
 objectOutputStream.writeObject(user);
 
 } catch (IOException e) {
 e.printStackTrace();
 }finally {
 if(objectOutputStream!=null){
 try {
 objectOutputStream.close();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
 }
 }
 
 
 private static <T> T objectInput(String path){
 
 ObjectInputStream objectInputStream=null;
 try {
 objectInputStream = new ObjectInputStream(new FileInputStream(path));
 
 return (T) objectInputStream.readObject();
 
 
 } catch (IOException | ClassNotFoundException e) {
 e.printStackTrace();
 }finally {
 if(objectInputStream!=null){
 try {
 objectInputStream.close();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
 }
 return null;
 }
 }
 
 | 
打印流
含义
可以输出任何类型的数据
注意点
当打印对象的时候,只是输出了对象.toString()结果。并不是将整个对象输出。
种类
- PrintStream
- PrintWriter [掌握]
案例
User.java
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | public class User {
 private String name;
 public User(String name){
 this.name = name;
 }
 @Override
 public String toString() {
 return "User [name=" + name + "]";
 }
 }
 
 | 
PrintTest.java
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | public class PrintTest {
 
 
 
 
 public static void main(String[] args) throws IOException {
 
 
 PrintWriter printWriter = new PrintWriter("C:\\result.txt");
 
 User user = new User("zs");
 printWriter.print(user);
 printWriter.print(11);
 printWriter.close();
 }
 }
 
 | 
线程
相关概念
- 串行 - 
- 多个事件依次执行 
 
- 并行 - 
- 多个事件在同一时刻同时执行 
 
- 并发 - 
- 在一段时间内多个事件发生  
 
- 进程 - 
- 一个正在运行软件,一个软件对应一个进程 - 一个进程中至少有个一个线程 
 
- 线程 - 
- 是进程中的执行分支(索引) 
 
进程和线程区别
- 每个进程都有独立的内存空间
- 一个进程至少要有一个线程
- 每创建一个线程都有自己的栈、本地方法区、程序计数器【TODO】
如何创建线程
入门案例
示意图
 
代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 
 | public class _01Thread {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 public static void main(String[] args) {
 
 
 Thread firstThread = new FirstThread();
 firstThread.start();
 
 for(int i=0;i<20;i++){
 System.out.println("Main,i="+i);
 }
 
 }
 }
 
 class FirstThread extends Thread{
 
 
 @Override
 public void run() {
 
 for(int i=0;i<20;i++){
 System.out.println("FirstThread,i="+i);
 }
 }
 }
 
 | 
常见的方法上
- Thread.currentThread() - 
- 获取当前线程对象 
 
- start - 
- 启动线程【此时是就绪状态并不是说马上执行该线程的任务,而是需要等待获得cpu运行时】 
 
- run - 
- 指定线程的任务 
 
- getId - 
- 获取线程的id 
 
- getName - 
- 获取线程的名称 
 
- setName - 
- 设置线程的名称,还可以在构造器中调用父类的super(String threadName) 
 
案例
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 
 | package com.neu.day11._04thread;
 public class _02Thread {
 
 
 
 
 
 
 
 
 
 public static void main(String[] args) {
 
 
 
 
 
 
 
 
 
 Thread one = new MyThread("java");
 one.start();
 
 
 
 
 Thread two = new MyThread("html");
 
 two.start();
 
 
 
 
 
 System.out.println("main....");
 
 }
 
 }
 
 class MyThread extends Thread{
 
 private String content;
 public MyThread(String content){
 super("thread:"+content);
 this.content = content;
 }
 
 
 
 
 
 @Override
 public void run() {
 
 
 
 
 System.out.println(this.getName()+"="+this.content);
 }
 }
 
 
 | 
示意图
 
两种方式
区别
- 实现方式可以共享资源,继承不可以共享资源
- 实现方式还可以继承其他类,继承方式不可以再继承其他类了 
- 资源共享方式有线程安全问题
案例
继承方式
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 
 | public class _01BuyTicket {	public static void main(String[] args) {
 
 Thread one = new BuyThreader();
 Thread two = new BuyThreader();
 
 one.start();
 two.start();
 }
 
 }
 
 class BuyThreader extends Thread{
 
 private int ticket = 10;
 
 
 @Override
 public void run() {
 
 while(ticket>0){
 System.out.println("当前购买的票是:"+ticket);
 ticket = ticket - 1;
 
 try {
 Thread.sleep(100);
 } catch (InterruptedException e) {
 
 e.printStackTrace();
 }
 }
 }
 }
 
 
 | 
实现接口方式
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 
 | package com.neu.day11._05thread;
 public class _02BuyTicket {
 
 
 
 
 
 
 
 
 
 
 
 public static void main(String[] args) {
 
 Runnable buyer = new Buyer();
 
 Thread one = new Thread(buyer);
 Thread two = new Thread(buyer);
 
 one.start();
 two.start();
 }
 
 }
 
 class Buyer implements Runnable{
 
 private int ticket=10;
 
 
 @Override
 public void run() {
 
 while(ticket>0){
 System.out.println("当前购买的ticket是:"+ticket);
 ticket--;
 }
 }
 
 }
 
 
 | 
线程安全
常见概念
- 线程安全 - 
- 多线程修改操作同一份资源数据不会错乱 
 
- 线程不安全 [线程安全问题] - 
- 多线程修改操作同一份资源带来的数据错乱。 
 
处理方案
案例一
同步方法
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 
 | package com.neu.day11._06safe;
 public class _01BuyTicket {
 
 
 
 
 
 
 
 
 
 
 
 public static void main(String[] args) {
 
 Runnable buyer = new Buyer();
 
 Thread one = new Thread(buyer);
 
 
 Thread two = new Thread(buyer);
 
 one.start();
 two.start();
 }
 }
 
 class Buyer implements Runnable{
 
 private  int ticket=10;
 
 
 @Override
 public void run() {
 buy();
 }
 
 
 private synchronized void buy(){
 
 while(ticket>0){
 System.out.println("购买的ticket是:"+ticket);
 
 try {
 Thread.sleep(100);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 
 ticket--;
 }
 }
 }
 
 | 
案例二
验证两个资源的监视对象不一样的时候,当线程1进入监视对象1的资源时,线程2是否可以进入监视对象2的资源?
结论可以
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 
 | public class _02TestMonitor {
 public static void main(String[] args) {
 
 Runnable buyer = new MyBuyer();
 
 Thread one = new Thread(buyer);
 
 
 Thread two = new Thread(buyer);
 
 one.start();
 two.start();
 }
 }
 
 class MyBuyer implements Runnable{
 private boolean sign=true;
 
 
 @Override
 public void run() {
 
 if(sign){
 sign=false;
 one();
 }else{
 two();
 }
 }
 
 private synchronized void one(){
 
 System.out.println("one....");
 try {
 Thread.sleep(4000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 }
 
 
 private synchronized void two(){
 System.out.println("two....");
 try {
 Thread.sleep(4000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 }
 }
 
 | 
案例三
同步代码块
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 
 | public class _03BuyTicket {
 
 
 
 
 
 public static void main(String[] args) {
 
 Runnable buyer = new Killer();
 
 Thread one = new Thread(buyer);
 
 
 Thread two = new Thread(buyer);
 
 one.start();
 two.start();
 }
 }
 
 class Killer implements Runnable{
 
 private int ticket=10;
 
 
 @Override
 public void run() {
 buy();
 }
 
 
 private void buy(){
 System.out.println("hello");
 
 synchronized (this){
 while(ticket>0){
 System.out.println("购买的ticket是:"+ticket);
 try {
 Thread.sleep(10);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 ticket--;
 }
 }
 }
 }
 
 | 
案例四
使用可重入锁
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 
 | public class _04BuyApple {
 
 
 public static void main(String[] args) {
 
 Runnable buyer = new BuyerApple();
 
 Thread one = new Thread(buyer,"one");
 Thread two = new Thread(buyer,"two");
 
 one.start();
 two.start();
 }
 
 }
 
 class BuyerApple implements Runnable{
 
 private ReentrantLock lock = new ReentrantLock();
 
 private int count=10;
 
 @Override
 public void run() {
 
 buy();
 }
 
 private void buy(){
 
 try {
 lock.lock();
 while(count>0){
 Thread thread = Thread.currentThread();
 System.out.println(thread.getName()+"购买了,苹果编号是:"+count);
 count--;
 }
 } finally {
 lock.unlock();
 }
 }
 }
 
 
 | 
单例
含义
某个类在程序运行期间最多只能创建一个对象
方式
懒汉式
步骤
- 构造器private 
- 对外提供获取实例的方法 - 
- 注意里面要考虑线程安全的问题 
 
代码
ATM.java
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 
 | public class ATM {
 private static ATM atm;
 
 private ATM(){
 
 }
 
 
 
 
 
 
 
 
 
 
 
 
 public static ATM getInstance(){
 if(atm==null){
 synchronized(ATM.class){
 if(atm==null){
 atm = new ATM();
 }
 }
 }
 return atm;
 }
 }
 
 | 
Test.java
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | public class Test {
 public static void main(String[] args) {
 ATM atmOne = ATM.getInstance();
 ATM atmTwo = ATM.getInstance();
 
 
 System.out.println(atmOne==atmTwo);
 }
 }
 
 | 
常见方法下
- isAlive
- setPriority
- getPriority
- isInterrupted
- interrupt
判断是否存活
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 
 | public class _01isAliveTest {
 
 public static void main(String[] args) throws InterruptedException {
 
 Thread thread = new MyThread();
 thread.start();
 
 Thread.sleep(1000);
 
 
 System.out.println(thread.isAlive());
 }
 
 }
 
 class MyThread extends Thread{
 @Override
 public void run() {
 for(int i=0;i<10;i++){
 System.out.println(i);
 }
 }
 }
 
 | 
线程优先级
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 
 | public class _02PriorityTest {
 public static void main(String[] args) throws InterruptedException {
 
 Thread oneThread = new Thread(){
 @Override
 public void run() {
 System.out.println("one的优先级是"+this.getPriority());
 }
 };
 
 
 Thread twoThread = new Thread(){
 @Override
 public void run() {
 System.out.println("two的优先级是"+this.getPriority());
 }
 };
 
 
 
 twoThread.setPriority(Thread.MAX_PRIORITY);
 oneThread.setPriority(Thread.MIN_PRIORITY);
 
 oneThread.start();
 twoThread.start();
 }
 }
 
 | 
线程中断
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 
 | public class _03InterruptTest {	
 
 
 
 public static void main(String[] args) throws InterruptedException {
 
 Thread thread = new NumThread();
 thread.start();
 
 Thread.sleep(100);
 
 thread.interrupt();
 }
 }
 
 class NumThread extends Thread{
 
 @Override
 public void run() {
 for(int i=0;i<100;i++){
 
 if(isInterrupted()){
 return;
 }
 
 try {
 Thread.sleep(20);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 System.out.println(i+"是否中断了"+isInterrupted());
 }
 }
 }
 
 |