java基础(14)编码格式修改,打印流,转换流,装饰者设计模式,进程与线程,创建线程三种方式及使用场景,start和run的区别,sleep睡眠

1.修改编码格式
InputStreamReader
OutputStreamWriter
以GBK 的编码格式进行读取 UTF-8的文件内容 则会出现乱码
想要保证读写过程中 文字不是乱码,则要保证,流和接触到的文件的编码格式一致

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
public class Test {
	public static void main(String[] args) throws IOException {
		try {
			InputStreamReader reader = new InputStreamReader(new FileInputStream("zz.txt"),"UTF-8");
			char[] cs = new char[10];
			int num = reader.read(cs);
			System.out.println(Arrays.toString(cs));		
			//设定编码GBK
			OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("dd.txt"),"UTF-8");
			writer.write(cs, 0, num);
			writer.flush();
		} catch (FileNotFoundException e) {		
			e.printStackTrace();
		}	
	}
}

在这里插入图片描述
在这里插入图片描述
2.打印流
PrintStream 帮助实现打印输出效果
System.out标准输出 输出到控制台

import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
public class Test2 {
	public static void main(String[] args) throws IOException {
		PrintStream ps = System.out;
		ps.println("aaa");		
		System.out.println("bbb");		
		PrintStream ps2 = new PrintStream("c.txt");
		ps2.println("bb");
		ps2.print("333");
		ps2.write(new byte[] {97,98,99,100});
		ps2.flush();		
		//字符打印流
		PrintWriter writer = new PrintWriter("e.txt");
		writer.write(new char[] {'a','b','c','d'});
		writer.println("aaaa");
		writer.print("aaaa");
		writer.flush();		
		//err 也是printStream流类型
		System.err.println("aaa");
	}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3.转换流
数据类型是InputStream
字节流转成字符流 InputStreamReader
字节流转成字符流 OutputStreamWriter
Scanner的nextLine方法的实现
一次读取一行

4.装饰者设计模式
耦合性低,提高重用性

public class Util {
	public void print99() {
		for (int i = 1; i < 9; i++) {
			for (int j = 1; j <= i; j++) {
				System.out.print(i+"*"+j+"="+i*j+"\t");
			}
			System.out.println();
		}
	}
}
public class UtilsSon extends Util{
	Util util;
	public UtilsSon(Util util) {	
		this.util = util;
	}
	@Override
	public void print99() {		
		System.out.println("九九乘法表");
		util.print99();
		System.out.println("再见");
	}	
}
public class Test {
	public static void main(String[] args) {
		Util util = new Util();
		util.print99();
		UtilsSon son = new UtilsSon(new Util());
		son.print99();
		// 增加了缓冲区
		// bis 依然还是可以进行读取
		// 也是利用了装饰者模式
		 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(""));
	}
}

在这里插入图片描述
5.进程与线程
进程
每一个独立运行着的软件,就叫做一个进程
独立性:不同的进程之间是独立的,相互之间资源不共享
动态性:进程在系统中不是静止不动的,而是在系统中一直活动的
并发性:多个进程可以在单个处理器上同时进行,且互不影响
线程
一个进程可以有多个线程,每个线程去处理一个特定的子任务。一个进程中至少包含一个线程
线程的执行是抢占式的
单核:只能同时干一件事
进程和线程的关系以及区别
一个进程可以包含多个线程,但是至少需要有一个线程,否则这个进程是没有意义的
进程间不能共享资源,但线程之间可以
系统创建进程需要为该进程重新分配系统资源,而创建线程则容易的多,因此使用线程实现多任务并发比多进程的效率高
在这里插入图片描述

6.多线程的实现
创建方式
1 继承Thread类
2 实现Runnable接口
3 实现Callable接口

1.继承Thread类

  1. 自定义类继承Thread
  2. 重写run方法
  3. 创建子线程对象
  4. 用start方法启动线程
    当两个线程互不相干,没有共享资源,自己只需要做自己的事情时,就可以使用继承Thread方法
    main 线程: 主线程,自己创建的叫做 子线程
    自定义子线程是因为有任务, 没有任务则不需要创建线程
    通过构造方法给子线程赋值名字,给子线程赋值名字setName(name);
public class Test2 {
	public static void main(String[] args) {
		MyThread t = new MyThread2("兔子");
		MyThread t2 = new MyThread2("乌龟");		
		t.start();
		t2.start();
	}
}
class MyThread extends Thread{	
	String name;	
	public MyThread(String name) {
		//1 给子线程赋值名字setName(name);
		// 2. 通过构造方法给子线程赋值名字
		super(name);
		this.name = name;
	}
	@Override
	public void run() {
		for (int i = 0; i < 30; i++) {
			System.out.println(Thread.currentThread().getName()+":"+i);
		}
		}
	}

在这里插入图片描述
例:实现四个窗口,每个窗口卖20张票

public class Test3 {
	public static void main(String[] args) {
		MyThread1 t1 = new MyThread1("窗口一");
		MyThread1 t2 = new MyThread1("窗口二");
		MyThread1 t3 = new MyThread1("窗口三");
		MyThread1 t4 = new MyThread1("窗口四");		
		t1.start();
		t2.start();
		t3.start();
		t4.start();		
	}
}
	class MyThread1 extends Thread{		
		public MyThread1(String name) {
			super(name);
		}
		int ticket=20;
		@Override
			public void run() {
			for (int i = 1; i <= 20; i++) {
			ticket--;					System.out.println(Thread.currentThread().getName()+"卖出了第"+i+"张票");
				}				
			}
	}

在这里插入图片描述
2 实现Runnable接口
更加适用于,拥有共享资源的情况

  1. 自定义一个实现类 实现Runnable接口
  2. 重写run方法
  3. 创建线程对象,任务
  4. 创建Thread对象,并且将实现类对象作为参数传入Thread构造方法中
  5. start启动线程
    创建匿名内部类时
public class Test4 {
	public static void main(String[] args) {
		// 叫做Runnable对象  只是一个资源对象, 不是线程
				Ticket ticket = new Ticket();				
				// 创建线程对象
				Thread t = new Thread(ticket);
				Thread t2 = new Thread(ticket);
				Thread t3 = new Thread(ticket);
				Thread t4 = new Thread(ticket);				
				// 四个线程共享了一个ticke他空间				
				t.start();
				t2.start();
				t3.start();
				t4.start();				
				// 常用格式
				// 如果只想创建一个子线程 的时候 可以采用这种方式  匿名内部类的方式
				new Thread(new Runnable() {
					@Override
					public void run() {
						for (int i = 0; i < 20; i++) {
							System.out.println("i"+i);
						}
					}
				}).start();				
			}
		}
	class Ticket implements Runnable{			
			int tickt= 100;			
			@Override
			public void run() {
				while(tickt>0){
					tickt--;					System.out.println(Thread.currentThread().getName()+"卖了"+(100-tickt)+"张票"+"还有"+tickt+"张");
				}
			}
		}

在这里插入图片描述

3 实现Callable接口

  1. 定义实现类,实现Callable<线程返回值类型>
    2.重写call()方法

  2. 创建实现类对象, 但是他不是一个任务

  3. 创建FutrueTask<线程返回值类型> 将线程实现类作为参数传入到FutrueTask的构造方法中

  4. 创建线程Thread对象, 并且将FutrueTask对象作为参数传入构造方法
    6.start() 启动线程
    适用于: 想要得到线程结果的情况

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Test5 {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		MyCallable callable = new MyCallable();
		FutureTask<Integer> task = new FutureTask<>(callable);
		Thread thread = new Thread(task);
		thread.start();
		// 线程启动以后, 就会计算结果, 计算 就可以获取返回结果
		// Integer integer = callable.call();// 仅仅是以方法调用的方式来实现的
		// System.out.println(integer);
		// 子线程执行完毕以后给返回的结果
		Integer integer = task.get();
		// 如果主线程执行到这,子线程还没有执行完毕, 主线程则会阻塞,直到等到子线程执行完毕,返回结果
		System.out.println(integer);
	}
}
class MyCallable implements Callable<Integer> {
	@Override
	public Integer call() throws Exception {
		int sum = 0;
		for (int i = 0; i <= 10000; i++) {
			sum += i;
		}
		Thread.sleep(2000);
		return sum;
	}
}

在这里插入图片描述
7.使用场景
继承Thread方法:没有共享资源,各自线程使用自己属性的情况时使用
实现Runnable接口:1. 拥有共享资源
2. 如果操作比较简单 只想创建一个子线程对象的时候, 可以考虑使用线程匿名内部类的形式

new Thread(new Runnable() {						
	@Override
	public void run() {
	    for (int i = 0; i < 20; i++) {
        System.out.println("i"+i);
							}
						}
					}).start();

实现Callable接口:想要得到线程结果的情况

8.start和run的区别
start() 可以申请一个新的栈,可以启动子线程
run() 只是一个简单的方法调用
9.sleep()方法
写在哪个线程中就让哪个线程睡眠, 睡醒了以后就可以继续抢占cipu 单位毫秒

public class Test6 {
	public static void main(String[] args) {
		A a = new A();
		a.start();		
		System.out.println("aaa");
		System.out.println("aaa");
	}
}
class A extends Thread{
	@Override
	public void run() {
		for(int i  = 0; i<10;i++){
			System.out.println("haha");
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("heheh");
		}		
	}
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值