欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java: ----- 多线程、IO流、字符流(Buffered缓冲加强版)Copy

程序员文章站 2024-03-04 21:39:54
...

多线程

进程:正在运行的程序.
线程:每一个进程中都会有多个任务,每个任务就是一个线程.
单线程:程序中只有一个任务,只有一条执行路径.
多线程:程序中有多个任务,有多条执行路径.

  • 注意:进程想要执行必须抢到cpu的执行权.进程中如果线程较多抢到cpu的概率就会比较高.
    但是不保证一定能抢到,因为cpu的执行是随机性的.

并行:在某一个时间点上同时执行多个.
并发:在某一个时间点上只能执行一个.

多线程的实现方式

方式1:继承Thread ***

  • 1.创建自定义类继承Thread
  • 2.覆盖run方法
  • 3.创建对象
  • 4.启动线程 start()

方式2:实现Runnable接口 ***

  • 1.自定义类实现Runnable
  • 2.覆盖run方法
  • 3.创建对象
  • 4.创建Thread对象将第3步作为参数
  • 5.启动线程

第二种方式好一些,避免了java单继承带来的局限性.

Thread中的方法:

  • String getName():返回此线程的名称 ***
  • void setName(String name):设置线程名称 ***
  • static Thread currentThread():返回对当前正在执行的线程对象 ***
  • int getPriority():返回此线程的优先级
  • void setPriority(int newPriority):更改此线程的优先级
  • static void sleep(long millis):睡眠 ***
  • void join():等待这个线程死亡 *** t.join 只用t线程执行完毕后 才会执行当前线程

堆空间:

多进程之间的堆空间是相互独立的,多线程之间共用一个堆空间。例如两个线程创建的对象放在一个堆空间当中。

栈空间:

每一个线程都有独立的栈空间,用来存储局部变量,每当启动一个线程虚拟机就会为它创建一个新的栈空间。

线程安全问题

线程不安全:

  • 多个线程操作同一个对象(临界资源),破坏了不可分割的操作(原子性操作),就会产生数据不安全问题.

如何解决?

  • 多个线程访问临界资源,保证原子性操作不被破坏所以需要同步(线程安全|同步).这是一个整体代码,要么不执行,如果执行必须保证其他线程无法操作这段代码.java
    为这种思想提供了技术:同步代码块
synchronized (对象(锁标记)) {
			原子性操作
}
  • 只有拿到锁标记的线程才能进入同步代码块
  • 同步方法: 将synchronized关键字定义在方法上,同步方法的锁对象是: this

死锁

  • :两个或者多个线程之间产生了相互等待的情况.
  • 如何解决死锁 – 等待唤醒机制
  • void wait():当前线程处于无限期等待. 该方法必须在同步代码块中才能使用.调用后会释放该线程拥有的所有锁标记.调用wait会使当前线程进入到当前锁对象的等待队列.

例如: t1线程 、o.wait 、 o对象的等待队列为【t1,t2】并且是去锁标记

  • void notify() | notifyAll() : 释放锁对象上等待的单个线程(上例中t1)|多个线程(上例中t1、t2).该方法必须在同步代码块中才能使用. 注 :以上两个方法必须是锁对象调用.

例如 o.notify() | o.notifyAll():
释放锁对象上等待的单个线程(上例中t1)|多个线程

IO流

数据方向:输入流、输出流(读、写)
数据单位:字节流、字符流
流的功能:节点流、过滤流(节点流是完成数据的读写、过滤流:为其他流增加功能)

字节流

  • 字节输入流 InputStream(abstract) 父类
  • 字节输出流 OutputStream(abstract) 父类
  • 字符输入流 Reader(abstract)
  • 字符输出流 Writer(abstract)

FileInPutStream/FileOutPutStream文件字节流 节点流

字节流写

案例:

 //字节流写   给个文件名
FileOutputStream fileOutputStream = new FileOutputStream("D:\\giveFileName.txt");
fileOutputStream.write('A');
fileOutputStream.close();

java: ----- 多线程、IO流、字符流(Buffered缓冲加强版)Copy

如果文件已经存在 则覆盖
要想覆盖或者在末尾追加 则代码如下

 //字节流写   给个文件名  第二个参数表示是否要追加
FileOutputStream fileOutputStream = new FileOutputStream("D:\\giveFileName.txt",true);
fileOutputStream.write('A');
fileOutputStream.close();

java: ----- 多线程、IO流、字符流(Buffered缓冲加强版)Copy

字节流写方法

  • void write(int b):只写单个字节 ***
  • void write(byte[] b):写一个字节数组 ***
  • void write(byte[] b, int index, int len):写字节数组的一部分 ***
package io;
import java.io.*;
public class FileOutPutStream {
    public static void main(String[] args) throws Exception {
        //字节流写   给个文件名 第二个参数表示在原文件后追加
        FileOutputStream fileOutputStream = new FileOutputStream("D:\\giveFileName.txt",true);
        String string="ABCDEFGHIZKLMNOPQRSTUVWXYZ";
        byte[] bytes = string.getBytes();
        fileOutputStream.write(bytes);
        fileOutputStream.close();
    }
}

java: ----- 多线程、IO流、字符流(Buffered缓冲加强版)Copy

   FileOutputStream fileOutputStream = new FileOutputStream("D:\\giveFileName.txt",true);
        String string="abcdefg";
        byte[] bytes = string.getBytes();
        fileOutputStream.write(bytes,2,4);
        fileOutputStream.close();

java: ----- 多线程、IO流、字符流(Buffered缓冲加强版)Copy

异常try/catch处理方法

package io;
import java.io.*;
public class FileOutPutStream {
    public static void main(String[] args){
        //字节流写   给个文件名 第二个参数表示在原文件后追加
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream("D:\\giveFileName.txt",true);
            String string="ABCDEFG";
            byte[] bytes = string.getBytes();
            fileOutputStream.write(bytes,2,4);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (fileOutputStream!=null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

写换行等

如何实现数据的换行写入? * windows: \r\n * linux: \n * mac: \r

字节流读

FileInputStream
案例:

package io;
public class FileInputStream {
    public static void main(String[] args) throws Exception {
        java.io.FileInputStream fileInputStream = new java.io.FileInputStream("D:\\giveFileName.txt");
        while (true) {
            int read = fileInputStream.read();
            if (read==-1)break;
            System.out.print((char) read);
        }
        fileInputStream.close();
    }
}

java: ----- 多线程、IO流、字符流(Buffered缓冲加强版)Copy
高效率读取

package io;
public class FileInputStream {
    public static void main(String[] args) throws Exception {
        java.io.FileInputStream fileInputStream = new java.io.FileInputStream("D:\\giveFileName.txt");
        byte[] bytes = new byte[1024];
        while (true) {
            int read = fileInputStream.read(bytes);
            if (read==-1)break;
            for (int i = 0; i < read; i++) {
                System.out.print((char) bytes[i]+"\t");
            }
        }
        fileInputStream.close();
    }
}

java: ----- 多线程、IO流、字符流(Buffered缓冲加强版)Copy

字节流实现文件copy

package io;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileInAndOutCopy {
    public static void main(String[] args) {
        copy("D:\\giveFileName.txt", "D:\\newGiveFileName.txt");
    }
    static void copy(String oldName, String newName) {
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        try {
            fileInputStream = new FileInputStream(oldName);
            fileOutputStream = new FileOutputStream(newName);
            byte[] bytes = new byte[1024];
            while (true) {
                int read = fileInputStream.read(bytes);
                if (read == -1) break;
                fileOutputStream.write(bytes, 0, read);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream != null && fileOutputStream != null) {
                try {
                    fileInputStream.close();
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }
}

过滤流

DataInputStream/DataOutputStream

  • 读写八种基本类型和字符串

缓冲流(Buffered文件Copy)

  • 提高IO效率,减少访问磁盘的次数
package io;
import java.io.*;
import java.io.FileInputStream;

public class BufferedCopy {
    public static void main(String[] args) {
        copy("D:\\giveFileName.txt", "D:\\newGiveFileName.txt");
    }
    static void copy(String oldName, String newName) {
        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {
            FileInputStream fileInputStream = new FileInputStream(oldName);
            bufferedInputStream = new BufferedInputStream(fileInputStream);
            FileOutputStream  fileOutputStream = new FileOutputStream(newName);
            bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
            byte[] bytes = new byte[1024];
            while (true) {
                int read = bufferedInputStream.read(bytes);
                if (read == -1) break;
                bufferedOutputStream.write(bytes, 0, read);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bufferedInputStream != null && bufferedOutputStream != null) {
                try {
                    bufferedInputStream.close();
                    bufferedOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

字符流

  • Reader和Writer(字符流的父类 抽象类)
  • FileReader和FileWriter(文件字符流)
  • BufferedReader和BufferedWriter 缓冲流 提高IO效率 减少访问磁盘次数

为什么使用字符流?

  • 因为字节流在读取数据时每次读取1字节,而中文占用2字节空间,每次只能读取一个中文的一半.

Writer类中写数据的方法:

  • void write(int c):写一个字符
  • void write(char[] cbuf):写入一个字符数组.
  • void write(char[] cbuf, int off, int len):写字符数组的一部分
  • void write(String str):写入一个字符串 ***
  • void write(String str, int off, int len):写字符串的一部分

字符流读数据的方法:

  • int read():读一个字符 ***
  • int read(char[] cbuf):读一个字符数组 ***

flush()和close()的区别?***

  • flush:刷新
  • close:先刷新,再关流

字符流copy

package io;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class TestReadWrite {
    public static void main(String[] args) throws IOException {
        FileWriter fileWriter = new FileWriter("D:\\fileWrite.txt",true);
        fileWriter.write("今天是2020年7月9日\r\n");
        fileWriter.write("天气小雨\n");
        fileWriter.write("上午去西土城面试了\n");
        fileWriter.write("下午寝室面试了\n");
        fileWriter.write("一天又过去了哈哈真开心\n");
        fileWriter.close();
        FileReader fileReader = new FileReader("D:\\fileWrite.txt");
        char[] chars = new char[1024];
        while (true){
            int read = fileReader.read(chars);
            if (read==-1)break;
            for (int i = 0; i < read; i++) {
                System.out.print((char)chars[i]);
            }
        }

        fileReader.close();

    }
}

java: ----- 多线程、IO流、字符流(Buffered缓冲加强版)Copy

buffered加强的缓冲字符流拷贝

代码

package io;
import java.io.*;
public class BufferedReadWrite {
    public static void main(String[] args) throws IOException {
        FileWriter fileWriter = new FileWriter("D:\\fileWrite.txt",true);
        PrintWriter printWriter = new PrintWriter(fileWriter);
        printWriter.println("今天是2020年7月9日");
        printWriter.println("天气小雨");
        printWriter.println("上午去西土城面试了");
        printWriter.println("下午寝室面试了");
        printWriter.println("一天又过去了哈哈真开心");
        printWriter.close();
        FileReader fileReader = new FileReader("D:\\fileWrite.txt");
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        while (true){
            String line = bufferedReader.readLine();
            if (line==null)break;
            System.out.println("line = " + line);
        }
        fileReader.close();
    }
}

结果

java: ----- 多线程、IO流、字符流(Buffered缓冲加强版)Copy

相关标签: java