Day18 IO流(打印流、随机访问流)、线程、作业车站售票

IO流总结:
在这里插入图片描述

1、打印流

1.1PrintStream和PrintWriter
package Day18_IO3.print;/*
 * @author  pyh
 * @date  2020/12/9 0009 上午 9:58
 * @version 1.0
 * @since JDK1.8_241
 *  打印流
 *          PrintStream:打印字节流
 *          PrintWriter:打印字符流
 */

import org.junit.Test;
import java.io.*;

public class Demo01 {
    //打印字节流
    @Test
    public void test01() throws FileNotFoundException {
        PrintStream ps = new PrintStream(new FileOutputStream("E:\\File\\IO1.txt"));
        //ps.write(98);//b
        //打印流独有的打印方法,直接打印数据,不用转码
        ps.print(98);//98
        ps.close();
    }
    //打印字符流
    @Test
    public void test02() throws IOException {
        PrintWriter pw = new PrintWriter(new FileWriter("E:\\File\\IO1.txt"));
        //pw.write("abc");//abc
        pw.print("abc");//abc
        //pw.print(97);
        pw.close();
    }
}
1.2打印流的输入输出重新定向
package Day18_IO3.print;/*
 * @author  pyh
 * @date  2020/12/9 0009 上午 11:36
 * @version 1.0
 * @since JDK1.8_241
    输入、输出重新定向
 */

import org.junit.Test;
import java.io.*;
import java.util.Scanner;

public class Demo02 {
    //输出
    @Test
    public void test01() throws Exception {
        System.out.println("你还好吗?");
        //改变打印输出的方向
        System.out.println(new PrintStream(new FileOutputStream("IO.txt")));
        //标准的输出方向从控制台改变到IO.txt
        System.out.println("一般般");
    }

    //输入
    public static void main(String[] args) throws Exception {
        System.out.println("请输入你的名字:");
        //System.in是标准输入流,从控制台录入数据
        /*Scanner sc = new Scanner(System.in);
        String name = sc.next();
        System.out.println("你的名字是:"+name);*/

        //改变输入流
        System.setIn(new FileInputStream("IO.txt"));//修改标准输入流的方向
        Scanner sc1 = new Scanner(System.in);
        String name = sc1.next();
        System.out.println("你的名字是:"+name);
    }
}

练习:

package Day18_IO3.print;
//不通过Scanner类获取控制台的数据
import java.io.*;

public class Demo03 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        String str = br.readLine();
        System.out.println("控制台录入:"+str);
    }
}

2、随机访问流

package Day18_IO3.print.random;/*
        RandomAccessFile:随机访问流
            r:只读    rw:打开以便读取和写入
 */

import org.junit.Test;
import java.io.RandomAccessFile;

public class Demo01 {
    //随机访问流输出流
    @Test
    public void test01() throws Exception {
        RandomAccessFile rw = new RandomAccessFile("E:\\File\\IO1.txt","rw");
        rw.write("xiaohai".getBytes());
        rw.close();
    }
    //指定文件访问
    @Test
    public void test02() throws Exception {
        RandomAccessFile rw = new RandomAccessFile("E:\\File\\IO1.txt","rw");
        /*//设置偏移量,从偏移量开始写入并覆盖。
        rw.seek(1);//源文件内容xiaohai
        rw.write("123".getBytes());//写入x123hai*/

        rw.seek(rw.length());//从末尾开始写入
        rw.write("123".getBytes());
        rw.close();
    }
    //断点续传
    @Test
    public void test03() throws Exception {
        RandomAccessFile r = new RandomAccessFile("D:\\File\\text.mp4","r");
        RandomAccessFile rw = new RandomAccessFile("E:\\File\\text.mp4","rw");
        r.seek(rw.length());
        rw.seek(rw.length());
        //更改byte[1024]可以改变拷贝的速度,越小越慢,越打越快,最大为8192
        byte[] b = new byte[1024];
        int len;
        while ((len = r.read(b)) != -1){
            rw.write(b,0,len);
        }
    }
}

3、线程

3.1进程

进程:程序是静止的,只有真正运行时的程序,才被称为进程。

特点:

  • 单核CPU在任何时间点上。
  • 只能运行一个进程。
  • 宏观并行、微观串行。
3.2线程

线程:又称轻量级进程(Light Weight Process)。

  • 程序中的一个顺序控制流程,同时也是CPU的基本调度单位。
  • 进程由多个线程组成,彼此间完成不同的工作,交替执行,称为多线程。

比如:

  • 迅雷是一个进程,当中的多个下载任务即是多个线程。
  • Java虚拟机是一个进程,默认包含主线程(main),通过代码创建多个独立线程,与main并发执行。
3.3进程和线程区别
  • 进程是操作系统资源分配的基本单位,而线程是CPU的基本调度单位。
  • 一个程序运行后至少有一个进程。
  • 一个进程可以包含多个线程,但是至少需要有一个线程。
  • 进程间不能共享数据段地址,但同进程的线程之间可以。
3.4线程的组成

任何一个线程都具有基本的组成部分:

  • CPU时间片:操作系统(OS)会为每个线程分配执行时间。
  • 运行数据:
    堆空间:存储线程需使用的对象,多个线程可以共享堆中的对象。
    栈空间:存储线程需使用的局部变量,每个线程都拥有独立的栈。
  • 线程的逻辑代码。
3.5线程的创建方式

1、继承Thread类

package Day18_thread01;/*
 * @author  pyh
 * @date  2020/12/9 0009 下午 2:48
 * @version 1.0
 * @since JDK1.8_241
    线程的执行由CPU决定,多线程的表现是CPU快速来回切换不同的线程,达到多条线程同时执行的效果

        线程的创建方式:
            1、自定义线程类继承Thread类,重写run(),实例化线程类,通过对象调用start()启动线程
            2、自定义任务类实现Runnable接口,重写run(),实例化任务类对象,再实例化Thread类对象,在实例化
            Thread对象的时候,通过构造方法传递任务类对象,通过Thread类的对象调用start()启动线程
            3.实现Callable接口,重写call()
            4.通过线程池的方式获取线程并开启
 */

public class Demo01 {
    public static void main(String[] args) {
        MtThread1 thread1 = new MtThread1();
        MtThread2 thread2 = new MtThread2();
        //thread1.run();//调用方法
        thread1.start();//启动线程
        thread2.start();
        for (int i = 0; i < 100; i++) {
            System.out.println("主线程:"+i);
        }
    }
}
class MtThread1 extends Thread{
    //重写run()
    public void run(){
        for (int i = 0; i < 100; i++) {
            System.out.println("子线程1:"+i);
        }
    }
}
class MtThread2 extends Thread{
    public void run(){
        for (int i = 0; i < 60; i++) {
            System.out.println("子线程2:"+i);
        }
    }
}

2、实现Runnable接口

package Day18_thread01;/*
 * @author  pyh
 * @date  2020/12/9 0009 下午 3:19
 * @version 1.0
 * @since JDK1.8_241
        自定义任务类实现Runnable接口,重写run(),实例化任务类对象,再实例化Thread类对象,在实例化
            Thread对象的时候,通过构造方法传递任务类对象,通过Thread类的对象调用start()启动线程
 */

public class Demo02 {
    public static void main(String[] args) {
        //实例化任务类对象
        test1 test1 = new test1();
        //再实例化Thread类对象
        Thread thread = new Thread(test1);
        thread.start();//启动线程

        for (int i = 0; i < 100; i++) {
            System.out.println("主线程:"+i);
        }
    }
}
class test1 implements Runnable{
    //重写run()
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("子线程2:"+i);
        }
    }
}
3.6线程的睡眠
package Day18_thread01.sleep;/*
 * @author  pyh
 * @date  2020/12/9 0009 下午 4:46
 * @version 1.0
 * @since JDK1.8_241
    睡眠:每打印一句让线程休眠1毫秒
 */

public class Demo01 {
    public static void main(String[] args) throws InterruptedException {
        MyThread thread = new MyThread();
        thread.start();
        for (int i = 0; i < 100; i++) {
            System.out.println("主线程:"+i);
            Thread.sleep(1);
        }
    }
}
class MyThread extends Thread{
    public void run(){
        for (int i = 0; i < 100; i++) {
            System.out.println("子线程..."+i);
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

练习:通过控制台不断打印时间

package Day18_thread01.sleep;
import java.text.SimpleDateFormat;
import java.util.Date;
//通过控制台不断打印时间
public class Demo02 {
    public static void main(String[] args) throws InterruptedException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        while (true){
            //睡眠时间 1s = 1000ms
            Thread.sleep(1000);
            String time = sdf.format(new Date());
            System.out.println(time);
        }
    }
}
3.7临界资源

临界资源:多条线程同享一份数据

package Day18_thread01.resource;/*
 * @author  pyh
 * @date  2020/12/9 0009 下午 4:39
 * @version 1.0
 *      临界资源:多条线程同享一份数据
 */

public class Demo01 {
    public static void main(String[] args) {
        //开启线程
        for (int i = 0; i < 10; i++) {
/*            MyThread thread = new MyThread();
            thread.start();*/
            new MyThread().start();
        }
    }
}
class MyThread extends Thread{
    //临界资源
    static int count = 1;

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(count++);
        }
        System.out.println(Thread.currentThread().getName()+":"+count);
    }
}

线程的生命周期
在这里插入图片描述

4 车站售票

这个作业出现一些问题,例如:几个窗口重复售同一张票;票数为负数才售票结束。

解决这个问题的方法需要用到多线程即明天(Day19)学到的多线程。

package Day18_thread01.resource;/*
 * @author  pyh
 * @date  2020/12/9 0009 下午 7:14
 * @version 1.0
 * @since JDK1.8_241
 *      作业:车站售票,10个窗口出售1000张票
 *              窗口001出售第1000张票
 *              窗口002出售第999张票
 *              窗口007出售第998张票
 *              ...
 *              窗口005出售第1张票
 *              窗口001售票结束
 *              窗口002售票结束
 *              窗口003售票结束
 *              ...
 *              窗口0010售票结束
 */

public class Demo02 {
    public static void main(String[] args) {
        //开10个窗口
        for (int i = 0; i < 10; i++) {
            MyThread1 thread = new MyThread1();
            thread.start();
            //new MyThread1().start();
        }
    }
}
class MyThread1 extends Thread{
    static int count = 1000;
    @Override
    public void run() {
        while (count >= 0){
            if (count == 0){

            }else{
                System.out.println(Thread.currentThread().getName()+"出售第"+count+"张票");
            }
            count--;
        }
        try {
            Thread.sleep(1);
            System.out.println(Thread.currentThread().getName()+"售票结束!!!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值