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类
- 自定义类继承Thread
- 重写run方法
- 创建子线程对象
- 用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接口
更加适用于,拥有共享资源的情况
- 自定义一个实现类 实现Runnable接口
- 重写run方法
- 创建线程对象,任务
- 创建Thread对象,并且将实现类对象作为参数传入Thread构造方法中
- 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接口
-
定义实现类,实现Callable<线程返回值类型>
2.重写call()方法 -
创建实现类对象, 但是他不是一个任务
-
创建FutrueTask<线程返回值类型> 将线程实现类作为参数传入到FutrueTask的构造方法中
-
创建线程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");
}
}
}