管道流与等待/通知交叉备份

一、通过管道进行线程间通信

1.1 管道流pipeStream

一种特殊的流,用于在不同线程之间直接传送数据。一个线程发送数据到输出管道,另一个线程从输入管道中取数据。通过使用管道,实现不同线程之间的通信,而无需借助于类似临时文件的东西。

1.2 jdk提供的用于线程通信的类

  • PipedInputSream和PipedOutputStream
  • PipedReader和PipedWriter

1.3 字节流方式读取

读数据:

public class readData {
    public void readMehtod(PipedInputStream input) throws IOException {
        System.out.println("Read开始了");
        byte[] byteArray = new byte[20];
        int flag = input.read(byteArray);
        while(flag != -1){
            String Data = new String(byteArray, 0, flag);
            System.out.println(Data);
            flag = input.read(byteArray);
        }
        input.close();
    }
}

写数据:


public class writeData {
    public void writeMethod(PipedOutputStream out) throws IOException {
        System.out.println("write");
        for (int i = 0; i < 300; i++) {
            String outDate = " " + i;
            out.write(outDate.getBytes());
            System.out.println(outDate);
        }
        out.close();
    }

}

读数据线程:

public class readThread extends Thread {
    readData a;
    PipedInputStream in;
    public  readThread(readData a, PipedInputStream in){
        this.a = a;
        this.in = in;
    }

    @Override
    public void run() {
        try {
            a.readMehtod(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

写数据线程:


public class writeThread extends Thread{
    writeData a;
    PipedOutputStream out;
    public writeThread(writeData a, PipedOutputStream out){
        this.a = a;
        this.out = out;
    }

    @Override
    public void run() {
        try {
            a.writeMethod(out);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

测试方法:

public class test {
    public static void main(String[] args) throws IOException {
        PipedInputStream in = new PipedInputStream();
        PipedOutputStream out = new PipedOutputStream();
        in.connect(out);
        readData a = new readData();
        writeData b = new writeData();
        writeThread write = new writeThread(b, out);
        readThread read = new readThread(a, in);
        write.start();
        read.start();
    }
}

1.4 字符流方式读取

读方法:

public class readData {
    public void readMehtod(PipedReader input) throws IOException {
        System.out.println("Read开始了");
        char[] byteArray = new char[20];
        int flag = input.read(byteArray);
        while(flag != -1){
            String Data = new String(byteArray, 0, flag);
            System.out.println(Data);
            flag = input.read(byteArray);
        }
        input.close();
    }
}

写方法:

public class writeData {
    public void writeMethod(PipedWriter out) throws IOException {
        System.out.println("write");
        for (int i = 0; i < 300; i++) {
            String outDate = " " + i;
            out.write(outDate);
            System.out.println(outDate);
        }
        out.close();
    }
}

只有管道中写入了数据,读线程才能读出数据,否则读线程会阻塞in.read(xx)方法上。

1.5 字符与字节的区别

https://www.cnblogs.com/mrjade/p/6861107.html

二、等待/通知交叉备份

2.1 问题描述

创建20个线程,10个线程将数据备份到A数据库中,10个线程将数据备份到B数据库中,并且备份到数据库A与备份到数据库B是交叉运行的。

2.2 解决

类代码:

package backup;

public class backup {
    volatile private boolean flag = false;
    synchronized public void backupA(){
        while(flag == false){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + "*****");
        }
        //A备份完,轮到B
        this.flag = false;
        this.notifyAll();

    }
    synchronized  public void backupB(){
        while(flag == true){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + "-----");
        }
        //B备份完,轮到A
        flag = true;
        notifyAll();
    }
}

A备份线程:

public class backupA extends Thread {
    backup a;
    public backupA(backup a){
        this.a = a;
    }

    @Override
    public void run() {
        a.backupA();
    }
}

B备份线程

package backup;

public class backupB extends Thread{
    backup b;
    public backupB(backup b){
        this.b = b;
    }

    @Override
    public void run() {
        b.backupB();
    }
}

运行类:

public class test {
    public static void main(String[] args) {
        backup backup = new backup();
        for (int i = 0; i < 10; i++) {
            backupA a = new backupA(backup);
            a.start();
            backupB b = new backupB(backup);
            b.start();
        }
    }
}

结果:

Thread-1-----
Thread-1-----
Thread-1-----
Thread-1-----
Thread-1-----
Thread-0*****
Thread-0*****
Thread-0*****
Thread-0*****
Thread-0*****
.......
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值