JAVA #(三)线程,流,容器和接口

本文主要介绍了JAVA中的线程概念及其常用方法,包括线程同步问题的解决;接着讲解了流的基本概念、分类及常用方法,如字节流、字符流、缓冲流等;最后探讨了JAVA中的容器,特别是Iterator接口及其在集合类中的应用,如set、list和map的特性。

线程

def:线程是一个程序里的不同执行路径,(两块代码可以同时宏观执行)
使用:

  • 继承Thread类后,对run()方法进行重写
  • 或者实现runnable接口,实现run()方法
  • 调用start()方法
    tips:
    1.执行线程就是执行run()方法中的代码,一个对象只有一次start方法
    2.start()方法就是创建一个新线程,并自动调用该线程的run()方法

大体实现代码:

class A implements Runnable{
	...//实现了run方法
}
class B extends Thread{
	...//重写了run方法
}
A aa = new A();
Thread t = new Thread(aa);//构建线程对象必须要用runnable类型的对象作为参数
t.start();
//aa.start();//error,因为只有线程类才能调用start方法
B bb = new B();//本身已经继承线程,那么就是自己线程类
bb.start();//ok,线程自己start

常用方法

  • public final void setName(String name);//设置线程的名字
  • public static Thread currentThread();//返回执行线程类对象的引用
  • public final String getName();//返回线程的名字
  • Thread.currentThread().getName();//返回谁在执行线程
public class test {
    public static void main(String[] args) {
        A a1 = new A();
        a1.setName("a1");
        a1.start();
        A a2 = new A();
        a2.setName("a2");
        a2.start();
        A a3 = new A();
        a3.setName("a3");
        a3.start();
        //第一句输出一定是main
        System.out.println(Thread.currentThread().getName());
    }

}

class A extends Thread{

    @Override
    public void run() {
        super.run();
        System.out.println("正在执行:"+ Thread.currentThread().getName());
    }
}

线程控制的相关方法:

  • isAlive() //判断是否活着
  • getPriority() //获得优先级
  • setPriority() //设置优先级
  • ThreadSleep() //设置阻塞
  • join() //合并线程,把当前执行的线程暂停
  • yield() //设置为就绪状态
  • notify() //激活线程
    tips:线程是不能抛出异常的

线程同步问题:

public class test {
    public static void main(String[] args) {
        B b = new B();
        Thread t1 = new Thread(b);
        t1.start();
        Thread t2 = new Thread(b);
        t2.start();

    }

}

class B implements Runnable{
    private static int ticketNum = 100;
    private static String str = new String("123");
    @Override
    public void run() {
        while (true){
            synchronized (str){
                if(ticketNum > 0){
                    System.out.printf("%s线程正在卖第%d张票\n",Thread.currentThread().getName(),ticketNum);
                    ticketNum--;
                }else {
                    break;
                }
            }

        }
    }
}

若不限制代码互斥,就可能出现并发错误
synchronized(对象名a){代码块A}
其含义是:本线程判断a是否被其它线程占用,若是被占用那么本线程进入等待状态;若a没有被占用,那么就占用此对象并执行代码块A;在当前线程执行代码块A途中其它线程无法再执行代码块A,当本线程被执行完代码块的时候会释放a,让其它线程去竞争,CPU最终会选择其中一个进行执行.

**什么叫流:**用于数据传输的类,是数据的管道(只有数据通过它才能进行传输)
**流和类的关系:**流是一种类,用作于设备和程序之间的数据传输.
**原始流:**是数据源和数据的读写方法.
**原始流和包裹流的关系:**包裹流是依托与原始流.
流的分类:
1.四大基本流
字节流:InputStream/OutputStream
字符流:Reader/Writer
2.文件流:File+(四大基本流)

  • InputStream常用方法:
    public int read();
    public int read(byte[] b);
    public int read(byte[] b,int off,int len);
    public void close();
  • OutputStream常用方法:
    void write(int b);
    void write(byte[] b);
    void write(byte[] b,int off,int len);
    void close();
    void flush();
  • Reader常用方法:
    int read();
  • Writer常用方法:
    void write();

3.缓冲流:带有缓冲区的流;等价于Buffer+四大基本流
public BufferedInputStream bis;
public BufferedOutputStream bos;
public BufferedReader br;
public BufferedWriter bw;
4.数据流:
能够以一种与机器无关的方式直接将java中的基本类和String类型 的数据写到字节输出流,属于包裹流.
本质是一个数组和字节输入/出流.
可以实现其它类型转换为byte类型的数据流.
public ByteArrayInputStream bais;
public ByteArrayOutputStream baos;
5.转换流:
System.in是字节输入流(InputStream)的子类.
InputStreamReader可以将Inputstream转换为Reader类.
可以得到:基本流+Reader类可以实现将基本流转换为Reader流
6.print流
print流只有输出,没有输入.
printStream在基本字节输出流的基础上提供了增强功能,可以方便地输出各种类型的数据,比数据输出流只能输出Byte流更强,不限于byte
7.实现对象序列化的流
ObjectOutputStream
ObjectInputStream
可以将对象(Object)直接转换成字节流后直接写入硬盘或网络中.
tips:要实现序列化必须实现serializable接口
各类型流的基本应用
public static void main(String[] args) throws IOException {

    BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:\\Users\\Acos\\Pictures\\chrome.ico"));
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\Temp\\streamTest.png"));
    
    byte[] buffer = new byte[1024];
    int len = bis.read(buffer);
    while (-1 != len){
        bos.write(buffer,0,len);
        len = bis.read(buffer);
    }
    bos.flush();
    bos.close();
    bis.close();
}

容器Iterator

定义:
能够放入很多不同类型对象的对象,不是数组,又称集合;
可以代替数组,弥补数组的长度难扩充,类型必须相同的缺点.
Iterator的方法
boolean hashNext();//判断当前游标后面是否有元素
Object next();//返回当前游标右边的元素
void remove();//删除最近返回的元素
容器的数学分类:

  • set:元素无序,不重复
  • list:元素有序,允许重复
  • map:保存成对的键值对,一个元素一个键值对,一个键映射一个值
    容器的继承关系:
    Iterator:Collection,Map ||这一层全是接口
    Collection:set,list ||下面是实体类
    set:hashset
    list:linklist,arraylist ||两者都实现了list接口,但是前者底层是双向链表,后者是数组
    Map:hashmap

Collection的常用方法:

  • sort(list);//双轴快速正向排序list中的元素
  • reverse(list);//倒序list
  • fill(list,object);//将list填满object
  • binarySearch(list,object);//折半查找,在list找object

hashcode()方法与equals()方法介绍:
将对象放入hashset容器:
1.hashcode()方法决定元素放入容器时的hashcode
2.equals()方法决定,当对象的hash相同时,后面的元素相同与否
tips:注意原本的hashcode()方法与equals()方法原本的判断依据是对象的地址,当我们直接定义类时,最好重写一下hashcode()和equals()方法,改变其的判断依据达到我们想要的效果(比如改变判断依据是对象的值).

HashMap:
几个概念:
1.哈希表:保存数据的主键,用算法计算出以当前主键为主键的数据存储的位置,将数据保存到当前位置上.
tips:哈希表中不允许重复的键
2.映射(map):将键和键值映射的集合,每个元素都包含一对键对象和值对象.

实现HashMap(K,V)的遍历:

	HashMap hm = new HashMap();//创建hashMap
	Set<Intager> s = hm.keySet();//获得hashMap的键值,组成集合
	Iterator<Intager> it = s.iterator();//对接口的类型进行指定
	while(it.hashNext()){
		Intager Key = (Intager)it.next();
		System.out.println(hm.get(Key));
	}

泛型:
在容器的基础上,限定进入容器的数据类型;
表现形式为"<数据类型>"
比如ArrayList list = new ArrayList();//list只能够放入String类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值