2021-11-05 迈向程序猿的第二十二步

目录

一. 线程安全的HashMap

 二. 队列

2.1 Queue队列接口

2.2 ConcurrentLinkedQueue实现类

2.3 阻塞队列

2.4 有界队列应用

三. IO流

3.1 字节节点流

3.2 字节缓冲流


一. 线程安全的HashMap

//ConcurrentHashMap: 并发的HashMap(前提是安全)
//Coolections中也提供了线程安全的Map,只不过锁的是整个hash表

public class Test1 {
	public static void main(String[] args) {
		Map<String, String> map = new ConcurrentHashMap<String, String>();
		for(int i=0;i<16;i++) {
			final int temp = i;
			new Thread(new Runnable() {
				@Override
				public void run() {
					map.put(Thread.currentThread().getName(), "value:"+temp);
					System.out.println(map);
				}
			}).start();
		}
	}
}

 二. 队列

2.1 Queue队列接口

//Queue:队列的接口,特点:先进先出
//LinkedList实现类就实现了该接口
public class Test1 {
	public static void main(String[] args) {
		Queue<Integer> queue = new LinkedList<Integer>();
		/*
		//如果没有元素,继续移除,会报异常
		queue.add(1);
		queue.add(3);
		queue.add(2);
		System.out.println(queue.element());  //取第一个元素
		System.out.println(queue.remove());   //取第一个元素,并移除
		*/
		
		
		//如果队列没有元素,则返回null--推荐
		queue.offer(1);
		queue.offer(3);
		queue.offer(2);
		
		System.out.println(queue.peek());  //取元素不移除
		System.out.println(queue.poll());  //取元素并移除
		System.out.println(queue);
	}
}

2.2 ConcurrentLinkedQueue实现类

//ConcurrentLinkedQueue: 在多线程中,性能最高的并发的队列
//内部采用了CAS无锁交换算法进行存储
//有3个参数:  V(要改变的变量)      E(预期值)      N(新值)
//执行过程中,如果V=E,那么N就可以改变V变量的值了

public class Test2 {
	public static void main(String[] args) throws InterruptedException {
		Queue<Integer> queue = new ConcurrentLinkedQueue<Integer>();
		
		Thread th1 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				for(int i=1;i<=5;i++) {
					queue.offer(i);
				}
			}
		});
		th1.start();
		
		Thread th2 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				for(int i=6;i<=10;i++) {
					queue.offer(i);
				}
				
			}
		});
		th2.start();
		
		th1.join();  th2.join();
		

		
		for(int i=1;i<=10;i++) {
			System.out.println(queue.poll());
		}
		
		
	}
}

2.3 阻塞队列

//BlockingQueue:阻塞队列的接口
//实现类有: 有界队列ArrayBlockingQueue(推荐),无界队列LinkedBlockingQueue
//有界队列是有长度限制    无界队列可以认为没有
//有两个阻塞方法: put,take ,该阻塞方法的使用类似于生产者消费者用法
//put:一般不能超过有界队列长度,超过了阻塞       take,没有值时阻塞
public class Test3 {
	public static void main(String[] args) throws InterruptedException {
		BlockingQueue<String> queue = new ArrayBlockingQueue<String>(3);
		queue.put("苹果");
		queue.put("香蕉");
		queue.put("橘子");
		System.out.println(queue.take()); //取出并移除
		queue.put("西瓜"); //限制存3个,第4个阻塞了
		System.out.println(queue.take()); //取出并移除
		System.out.println(queue);
	}
}

2.4 有界队列应用

//通过阻塞队列模拟生产者消费者模型
//案例:生产者和消费者个打印1~100,每次最多生产或消费4个
public class Test4 {
	public static void main(String[] args) {
		BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(4);
		
		//负责生产的线程
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				for(int i=1;i<=100;i++) {
					try {
						queue.put(i);
						System.out.println("已经生产了第"+i+"件货");
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
				}
			}
		}).start();
		
		
new Thread(new Runnable() {
			
			@Override
			public void run() {
				for(int i=1;i<=100;i++) {
					try {
						System.out.println("已经消费了第"+i+"件货");
						queue.take();
						
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
				}
			}
		}).start();
	}
}

三. IO流

概念:程序与文件之间存储数据的通道

流的划分:
1. 按方向划分: 输入流,输出流
输入流:将文件中的数据读到程序中
输出流:将程序的数据写到文件中

2. 按单位划分: 字节流,字符流
字节流:读写最小单位,按一个一个字节读写,效率低;读写所有文件(音频,视频,图片)
字符流:按一个一个字符读写,效率高;只能读写文本文件

3. 按功能划分:节点流,处理流
节点流:基础流,没有经过处理的流
处理流:经过处理包装后的流,功能更为强大 

3.1 字节节点流

字节流的抽象父类:  OutputStream,InputStream

子类:
字节流的节点流:  FileOutputStream,FileInputStream

------输入流-------
//字节节点流的读取:FileInputStream
//细节: 实例化输出流,会自动创建文件; 实例化输入流,则不会自动创建
//注意:在项目中使用IO流,往往捕获更多,咱们测试案例,后续用抛出更方便
public class Test2 {
	public static void main(String[] args) {
		FileInputStream fis = null;
		try {
			fis = new FileInputStream("a.txt");
			//System.out.println((char)fis.read());  //读取一个码值对应的字符
			byte[] b = new byte[1024];
			int len;  //读取字节数组,返回长度
			while((len=fis.read(b)) != -1) {
				//byte[]-->String
				//从下标0位置挨个转字符串,转len个
				System.out.println(new String(b,0,len)); 
			}

		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			IOUtils.closeAll(fis);  //统一资源关闭---Closeable接口

		}
	}
}

-------统一资源关闭--------
public class IOUtils {
	public static void  closeAll(Closeable... cs) {
		for(Closeable c : cs) {
			if(c!=null) {
				try {
					c.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

3.2 字节缓冲流

 

------字节缓冲输出流-----
//字节缓冲流:BufferedOutputStream/BufferedInputStream
//带缓冲区的字节流--处理流(包装之后得到的流),减少与磁盘交互次数,提升了性能
//带两个参数的缓冲区对象,第二个参数是缓冲区大小,如果不指定默认为8192(1024*8,恒定值)
//越接近恒定值,缓冲区存储性能越好

public class Test1 {
	public static void main(String[] args) throws IOException {
		//BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("a.txt"));
		
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("a.txt"), 6);
		
		bos.write("hello,IO...".getBytes()); //缓冲区满了,也会写到磁盘文件
		//bos.flush();    //刷新缓冲区
		//bos.close();  //刷新缓冲区+close
	}
}


-------字节缓冲输入流--------
//读取缓冲区内容
public class Test2 {
	public static void main(String[] args) throws IOException {
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
		byte[] b = new byte[104];
		int len;
		while((len=bis.read(b))!=-1) {
			System.out.println(new String(b, 0,len));
		}
		IOUtils.closeAll(bis);
		
	}
}

(=-=,温馨提示!一定要多回头看看之前学过的内容,不然你永远不知道你记不起它的时候有多难受,小白今天脑袋就成了一坨江湖!一时半会蒙了,好记性不如烂键盘,千万要多敲!!!)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值