JAVA高级(上)简单总结

我的课本是分为六个章节进行了介绍:

这篇主要总结前三章。

  • 第一章 I/O流
  • 第二章 线程
  • 第三章 同步代码块
  • 第四章 网络编程
  • 第五章 XML解析
  • 第六章 设计模式

第一章 I/O流

1.1

I/O流的分类:

按照数据流向可以分为:

输入流和输出流

按照操作方式分为:

字节流 InputStream和OutputStream

字符流 Reader和Writer

1.2

I/0流能做什么?

在本地磁盘和网络上操作数据

1.3

字节流与字符流的区别:

字节流和字符流的区别在于每次读写的字节数不同;字符流是快读写,字节流是字节读写;字符流带有缓存,字节流没有。

1、字节流 :字节读写, 字节流(ASCII)处理二进制文件。

   可以传输音频,视频,图片,文本等,传输数据的基本单位为字节。

2、字符流:快读写 ,字符流(Unicode)处理文本文件。

只能传输纯文本,传输数据的基本单位为字符 字节流是由字节组成的; 字符流是由字符组成的。

Java里字符由两个字节组成. 1字符=2字节

1.4

File类常用的方法:

/*注意:只要涉及到盘符的都是双斜杠*/

package First;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
public class Text01 {
/*题目:在电脑硬盘中,查看E://text4/name目录是否存在,如果不存在,则创建该目录
 * 如果存在,则查找readme文件是否存在。如果readme.txt不存在,则创建readme.txt文件存在
 * 输出该文件的路径和大小*/
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
//		判断是否存在
		boolean flag=false;
//		创建file对象
		File directory=new File("E://text4/name");
//		判断目录是否存在
		if (directory.exists()) {
//			如果该目录存在,则获取该目录下所有的子文件和子目录
			File[]fileArrayFiles=directory.listFiles();
//			遍历fileArray[]数组
//			高级for循环格式:for(数据类型 变量名 被遍历的集合或数组)
			for (File file:fileArrayFiles) {
//				判断readme.txt是否存在
				if ("readme.txt".equals(file.getName())) {
//					如果存在
					System.out.println("存在");
					System.out.println("路径"+file.getAbsolutePath());
					System.out.println("大小"+file.length());
//					设置flag为true
					flag=true;
					break;
				}
			}
		}else {
//			如果不存在,则创建该目录
			directory.mkdirs();
		}
//		如果该文件在目录中不存在,则创建
		if (!flag) {
			try {
			File txtFile=new File(directory,"readme.txt");
			txtFile.createNewFile();
			System.out.println("文件已成功创建"+txtFile.getAbsolutePath());
			} catch (IOException e) {
				// TODO: handle exception
				e.printStackTrace();
			}
		}
	}

}

以下是老师上课讲的一个案例,我记下来了,但是我没有听懂,懂的宝宝可以评论区告诉我一下。我只会背代码,/(ㄒoㄒ)/~~

假设我有一部电影需要拷贝,如果说它比较大,比如我们有40G,那么如果是采取读取完毕之后统一写入会怎样?

因为日常生活的我们的内存只有32G,读取内容超过了内存,那么就会出现数据不完善.

所以我们应该采取读一部分,写一部分,这样才算合理的运用资源,边读边写。

拷贝原理:从需要拷贝的文件,到需要拷贝的副本。

1.通过字节输入流,将文件输入到电脑当中,保存到内存当中。

2.字节输出流,使用字节输出流,将文件输出成对应的文件。

3.先开先读,后开后读。

下面开始背代码了:

## 1.1字符流,用来处理字符集的转换

package First;

import java.awt.Frame;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;


public class Zifuliu1 {
	public static void main(String[] args) {
		 FileReader fr =null;
		  FileWriter fw=null;
		// TODO Auto-generated method stub

   `try {`
	`fr=new FileReader("E://笔记和作业//高级java//字符流更改文件/wen.txt");`
	`fw=new FileWriter("E://笔记和作业//高级java//字符流更改文件/古诗.txt");`
	 `int data;//用来接收我们的数据`
	  `//用字节数组装好`
	  `byte[]buf=new byte[1024];`
	  `while ((data=fr.read())!=1) {`
`//		将数据写入文件中`
		  `fw.write(data);`
	`}`
`} catch (Exception e) {`
`e.printStackTrace();`
`}finally {`
`try {`
		`if (fr!=null) {`
			`fr.close();`
		`}`
		`if (fw!=null) {`
			`fw.close();`
		`}`
`} catch (Exception e2) {`
	`e2.printStackTrace();`
`}`
`}`
	`}`

`}`

## 1.2字节流可以传输音频,视频,图片,文本等,传输数据的基本单位为字节。

`package First;`

`import java.io.FileInputStream;`
`import java.io.FileOutputStream;`
`import java.nio.Buffer;`

`public class zijieliu1 {`
`//使用字节流来拷贝文件`
	`public static void main(String[] args) {`
		`// TODO Auto-generated method stub`
  `FileInputStream fis=null;`
  `FileOutputStream fos=null;`

  `try {`
	`//  需要拷贝的文件`
	  `fis=new FileInputStream("E://笔记和作业//高级java//音乐素材/遗失的心跳.mp3");`
	`//  拷贝后的副本`
	  `fos=new FileOutputStream("E://笔记和作业//高级java//拷贝后的素材/遗失的心跳.mp3");`
	  ``
	  int data;//用来接收我们的数据
	  //用字节数组装好
	  byte[]buf=new byte[1024];
		long start=System.currentTimeMillis();//拷贝时间
	   while ((data=fis.read(buf))!=-1) {
		fos.write(buf,0,data);
	}
	long end=System.currentTimeMillis();
	System.out.println("拷贝时间为:"+(end-start));
	System.out.println("拷贝成功");


``	

`} catch (Exception e) {`
	`// TODO: handle exception`
	`e.printStackTrace();`
`}finally {`
	`try {`
		`if (fis!=null) {`
			`fis.close();`
		`}`
		`if (fos!=null) {`
			`fos.close();`
		`}`
	`} catch (Exception e2) {`
		`e2.printStackTrace();`
	`}`
`}`
	`}`

`}`

第二章 线程

2.1一个进程多个线程

什么是多线程?通俗来讲,为了提高CPU的利用率,从而更好完成任务,我们可以使用多个线程实现同一个功能内容,相当于找个多个人同时搬砖。

创建多线程的三种方式 1.继承Thread类(线程类)2.实现runnable接口实现线程 3.Callable接口创建线程

主要掌握前两种,推荐使用Runnable接口实现线程。

2.2第一种 继承Thread类

`步骤:

1.定义Thread类的子类

2.重写run()方法

3.创建子类实例,调用start启动线程

``package First;`

`import java.util.Iterator;`

`public class Xiancheng extends Thread{`
`//实现多线程的方式第一种,继承Thread类`
	`public static void main(String[] args) {`
		`// TODO Auto-generated method stub`
		`Xiancheng xiancheng=new Xiancheng("小猫");`
		`Xiancheng xiancheng2=new Xiancheng("小狗");`
		`Xiancheng xiancheng3=new Xiancheng("小鸡");`
		`//我们有三个线程,一个进程`
`//		为什么有的同学跑得快,因为是抢占式的 随机`
		`xiancheng.start();`
		`xiancheng2.start();`
		`xiancheng3.start();`

	}
	private String name;

`//	有参构造方法`
	`public Xiancheng(String name) {`
		`this.name=name;`
	`}`
`public void run() {`
	`for (int i = 0; i < 50; i++) {`
		`System.out.println(this.name+"同学跑了第"+i+"米");`
	`}`
`}`

2.3线程休眠应用,控制线程(sleep)

`public class Xianchenxiumian1 extends Thread{`


public static void main(String[] args) {
	// TODO Auto-generated method stub
	Xianchenxiumian1 xianchenxiumian1=new Xianchenxiumian1();
    xianchenxiumian1.start();

}
```

 `public void run() {`
	 `for (int i = 0; i < 20; i++) {`
		`System.out.println("今天天气真的好"+i);`
		`try {`
			`Thread.sleep(1000);`
		`} catch (Exception e) {`
		`e.printStackTrace();`
		`}`
	`}`
 `}`
``	

`}`

2.4第二种 实现Runnable接口实现线程

public class SellTicket implements Runnable{

/*题目是三个窗口一起卖火车票
卖50张火车票 */
	public static void main(String[] args) {
 
//创建实例
		SellTicket sellTicket=new SellTicket();
		Thread thread1=new Thread(sellTicket);
		thread1.setName("窗口一");
		Thread thread2=new Thread(sellTicket);
		thread2.setName("窗口二");
        Thread thread3=new Thread(sellTicket);
		thread3.setName("窗口三");`
//		实际启动
		thread1.start();
		thread2.start();
		thread3.start();
	}
private int ticket=50;
//多线程抢到了同一张票 
@Override
public void run() {
	// TODO Auto-generated method stub
	while (true) {
//实现接口的时候 我们查询线程名称需要用到thread.currentThread.getname
    System.out.println(Thread.currentThread().getName()+"出售第"+ticket+"张火车票");
	ticket--;
	if (ticket<=0) {
		break;
	}
	}

}

}

2.5线程和进程的关系:

进程是操作系统分配资源的基本单位,线程是操作系统执行和调度的最小单位,线程依赖于进程而存在,即线程和进程是依赖关系,通俗的讲,就是进程是一个容器,操作系统通过运行进程容器中的线程,来完成应用程序进程中的各项功能。

第三章 同步代码块和同步方法体

3.1多线程安全问题

线程抢占式执行会出现狼多肉少的情况,会导致线程不安全,多线程中会有抢占式调度

书本案例:

关于线程安全,有一个经典的问题——银行取钱。

取钱可以分为四个步骤:

1.用户输入取款金额

2.系统判断账户余额是否大于取款金额

3.如果余额大于等于取款金额,则取款成功,否则取款失败

//首先创建了Account类,再封装了账号String  no和余额double balance

//这是实现多线程模拟取钱 即多个线程对一个账户进行取钱

//必须是一个多线程的类

public class DreamThread extends Thread{

//取钱的账号对象
private Account account;

//当前线程所取的钱数
private double dreamAccount;

//	需要加入一个有参构造器,创建多线程的时候,就可以人为的设置人为的金额。

//	第一个参数代表线程是谁 取钱

public DreamThread(String name,Account account,double dreamAccount) {
     super(name);
     this.account=account;
     this.dreamAccount=dreamAccount;
}
	public void run(){
	
		account.draw(dreamAccount);
	}

	
	public static void main(String[] args) {
		// TODO Auto-generated method stubAccount account=new Account("1221",1200);	
	

new DreamThread("张三", account, 650).start();	

new DreamThread("李四", account, 650).start();

}

}



## 最后的运行结果是,两个线程对一个账户取钱。出现了-550元

因此为了避免这种问题的出现,

同步代码块的语法格式:

Sychronized(要锁定的对象){

//同步代码块执行体

}

同步方法的语法格式:

访问修饰符 sychronized 返回值类型 方法名称 (方法参数){

//同步方法的方法体

}

代码修改后:

public class SyncThread extends Thread{
//模拟用户账户
//    新建的类 对象
    private Account account;
//    当前线程所取的钱数
    private double drawAccount;

    public SyncThread(String name,Account account, double drawAccount) {
        super(name);
        this.account = account;
        this.drawAccount = drawAccount;

    }
    //执行
    public void run(){
       synchronized (account){
           if (account.getBalance()>=drawAccount){
               System.out.println(this.getName()+"\t取款成功!取出"+drawAccount);
//               修改余额
               account.setBalance(account.getBalance()-drawAccount);
               System.out.println("\t余额"+account.getBalance());
           }else{
               System.out.println(this.getName()+"取钱失败!余额不足");
           }
       }
    }

    public static void main(String[] args) {
//        创建一个账户
        Account account=new Account("221322421",1200);
//        模拟两个线程对一个账户取钱
        new SyncThread("张三",account,650).start();
        new SyncThread("李四",account,650).start();
    }
}
运行结果:
    张三	取款成功!取出650.0
	余额550.0
李四取钱失败!余额不足

3.2 模拟三个窗口出售50张车票的例子:

实现思路:

1.创建一个类并且继承Runnable接口

2.定义int类型的变量ticket,表示剩余的车票数量,并实现Runnable接口

3.创建同步方法sellTicket()。在该方法体,判断ticket的值是否大于0,如果大于0,则调用Thread.sleep(long mills)方法,让线程休眠50毫秒,并且打印出当前窗口的售票情况

4.重写run()方法,在 run()方法内,定义一个while死循环,在循环内,判断变量ticket是否大于0,小于0,结束循环,大于0,调用sellTicket方法

5.在main方法创建接口实例。

6.创建三条线程,并且为三条线程指定名称

7.依次启动线程

public class SellTicketBySync implements Runnable{
    private int ticket=50;

    @Override
    public void run() {
        while (true){
            if (this.ticket>0){
                sellTicket();
            }else {
                break;
            }
        }
    }
    public synchronized void sellTicket(){
        if (this.ticket>0){
            try{
//                线程休眠50毫秒
                Thread.sleep(50);
                System.out.println(Thread.currentThread().getName()+"出售第"+ticket--+"张车票");
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
//        创建Runnable 实例
        SellTicketBySync runnableInstance = new SellTicketBySync();
//        创建三条线程,并为线程指定名称
        Thread thread01=new Thread(runnableInstance,"窗口一");
        Thread thread02=new Thread(runnableInstance,"窗口一");
        Thread thread03=new Thread(runnableInstance,"窗口一");
        thread01.start();
        thread02.start();
        thread03.start();
    }
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值