美文网首页
java基础知识总结(四)

java基础知识总结(四)

作者: 路小白同学 | 来源:发表于2018-05-01 18:53 被阅读0次

    本文主要介绍一下几个方面:
    1.多线程
    2.I/O
    3.对象序列化
    4.异常处理

    1.多线程
    线程是在一个进程中并发的一个顺序执行的流程。
    线程的组成:
    1.cup 有OS负责分配
    2.Data 堆空间:存储对象(存储实例变量) 栈空间:存储局部变量。
    3.Code 由程序员指定 继承Thread类或者实现Runnable接口。

    实现方式:
    1.继承Thread 一个Thread对象表示一个线程

    eg:

    
    class myThread extends Thread
    {
        public void run() 
        {
            System.out.println("this is a test");
        }
    }
    

    2.实现Runnable接口
    eg:

    /**
     * 通过实现Runnable接口创建一个线程
     * @author DreamSea
     */
    public class ThreadTest implements Runnable {
        public void run() {
                System.out.println("I'm running!");
        }
    }
    

    线程运行状态如下图:


    thread.jpg

    线程的状态:

    新生状态(New): 当一个线程的实例被创建即使用new关键字和Thread类或其子类创建一个线程对象后,此时该线程处于新生(new)状态,处于新生状态的线程有自己的内存空间,但该线程并没有运行,此时线程还不是活着的(not alive);

    就绪状态(Runnable): 通过调用线程实例的start()方法来启动线程使线程进入就绪状态(runnable);处于就绪状态的线程已经具备了运行条件,但还没有被分配到CPU即不一定会被立即执行,此时处于线程就绪队列,等待系统为其分配CPCU,等待状态并不是执行状态; 此时线程是活着的(alive);

    运行状态(Running): 一旦获取CPU(被JVM选中),线程就进入运行(running)状态,线程的run()方法才开始被执行;在运行状态的线程执行自己的run()方法中的操作,直到调用其他的方法而终止、或者等待某种资源而阻塞、或者完成任务而死亡;如果在给定的时间片内没有执行结束,就会被系统给换下来回到线程的等待状态;此时线程是活着的(alive);

    阻塞状态(Blocked):通过调用join()、sleep()、wait()或者资源被暂用使线程处于阻塞(blocked)状态;处于Blocking状态的线程仍然是活着的(alive)

    死亡状态(Dead):当一个线程的run()方法运行完毕或被中断或被异常退出,该线程到达死亡(dead)状态。此时可能仍然存在一个该Thread的实例对象,当该Thready已经不可能在被作为一个可被独立执行的线程对待了,线程的独立的call stack已经被dissolved。一旦某一线程进入Dead状态,他就再也不能进入一个独立线程的生命周期了。对于一个处于Dead状态的线程调用start()方法,会出现一个运行期(runtime exception)的异常;处于Dead状态的线程不是活着的(not alive)。

    在线程t1中调用t2.join() t1阻塞,当t2进入终止状态时,t1回到可运行状态。

    线程同步:
    当多线程并发访问临界资源(同一对象)时,如果破坏了原子操作(不可分割的操作),就会造成数据不一致。

    //对o进行加锁的同步代码块
    Synchronized(o)
    {
    
    }
    

    任何对象都有一个互斥锁标记,用来分配给线程,只有拿到对象锁标记的线程,才能进入对该对象加锁的同步代码块。运行结束,线程进入同步代码块,释放锁标记
    只用线程拿到对象的锁标记才能进入代码块。

    锁池:任何对象都有一个空间,用来存放等待该对象锁标记的线程。

    一个线程可以同时拥有多个对象锁标记,当线程阻塞在锁池中事,不会释放已拥有的锁标记,由此可能造成死锁。所以就有了线程间的通信。

    线程间的通信:
    任何对象都有一个等待队列,用来存放线程。
    t1:o.wait(),必须放在对o加锁的同步代码块中,t1会释放它拥有的锁标记,同时t1阻塞在o的等待队列中。

    t2:o.notify()/notifyAll(),必须放在对o加锁的同步代码块中,从o的等待队列中,释放一个或全部线程。

    2.I/O
    java.iO.File
    File 对象,代表磁盘上的一个文件或者目录

    File f = new File("F:\\file.text");
    

    方法:
    f.createNewFile():创建文件
    f.delete():删除
    f.mkdir():创建文件夹
    f.exists():判断文件或目录是否存在
    f.isDirectory():判断文件对象所代表的是否是目录
    f.isFIle():是否是文件
    f.getAbsolutePatyh():获得绝对路径

    遍历:
    eg:

            File file = new File("F:\\javaTest");
            File[] fs = file.listFiles();
            for (File file2 : fs) 
            {
             System.out.println("路径是:+"+file2.getAbsolutePath());   
            }
        
    

    如果只想特殊后缀文件,如.zip
    可以使FileFilter过滤文件
    eg:

    package test;
    
    import java.io.File;
    import java.io.FileFilter;
    import java.io.IOException;
    import java.nio.file.DirectoryStream.Filter;
    
    public class ThreadFile {
    
        /**
         * @param args
         * @throws IOException 
         */
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
    
            File file = new File("F:\\javaTest");
            File[] fs = file.listFiles(new myFilter());
            for (File file2 : fs) 
            {
             System.out.println("路径是:+"+file2.getAbsolutePath());   
            }
        
    }
    }
    
    class myFilter implements FileFilter
    {
        public boolean accept(File f)
        {
            if (f.isDirectory())
            {
                return false;
            }
            else {
                
                if (f.getName().endsWith(".zip"))
                {
                return true;    
                }
                else {
                    return false;
                }
            }
        }
    }
    

    另一种写法:
    eg:

        File file = new File("F:\\javaTest");
            File[] fs = file.listFiles(new FileFilter() {
                
                @Override
                public boolean accept(File arg0) {
                    // TODO Auto-generated method stub
                    if (arg0.isDirectory())
                    {
                        return true;
                    }
                    if (arg0.isFile())
                    {
                        if (arg0.getName().endsWith(".zip"))
                        {
                            return true;
                        }
                    }
                    else
                    {
                        return false;
                    }
                    return false;
                    
                }
            });
            
            for (File file2 : fs)
            {
                if (file2.isFile())
                {
                    System.out.println(file2.getAbsolutePath());
                }
                else {
                    
                    System.out.println(file2);
                }
            }
    

    I/O流
    流:对象,用来子啊JVM和外部数据员之间传输数据

    按照不同的方面划分可以划分为不同的流
    按照数据方向:输入流 / 输出流
    按照数据的单位:字节流 / 字符流
    按照流的功能:节点流 / 过滤流

    字节流:以字节为单位,可以处理一切数据
    字符流:以字符为单位,只能处理文本数据

    节点流:实际传输数据的流
    过滤流:给节点流增强功能

    InputStream / OutputStream 字节流父类
    FileInputStream / FileOutputStream 字节流实现类
    创建输出流代码为:

        OutputStream os = new FileOutputStream("F:\\javaTest\2.text",true);
    

    文件不存在会自动创建
    true:表示文件存在会追加
    false:会覆盖以前的文件

    方法:

    write(int a):把字节a写进去
    write(byte[] bs):把字节数组bs全部写进去
    write(byte[] bs,int off,int len):把字节数组的一段写出去,有off位置len个数

    输出流FileInputStream
    用于读取一个文件
    eg:

    InputStream input = new FileInputStream("2.text");
            while(true)
            {
                int i = input.read();
                if (i == -1)
                {
                    break;
                }
                else {
                    System.out.println((char)i);
                }
            }
        input.close();
    

    int read():从文件中读取一个字节,返回-1结束
    int read(byte[] bs):从文件中读取多个字节,bs:返回值为实际读到的字节数,以-1结束。
    int read(byte[] bs,int off,int len):从文件中读的多个字节,放入bs中的一段,返回值为实际读到的字节数,以-1为结束。

    过滤流:DataInputStream / DataOutputStream
    过滤是为了增加节点流的功能,直接读写八种基本类型和字符串
    (对字符串的读/写方法是reatUTF/writeUTF)
    ,eg:写入一个长整形

        
            OutputStream os = new FileOutputStream("1.text",true);
            DataOutputStream out = new DataOutputStream(os);
            out.writeLong(10000);
            out.close();
    

    使用流读写文件一般分为四步:
    1.创建节点流
    2.封装过滤流
    3.读 / 写 数据
    4.关闭流

    缓冲数据流(一般写文件时用的较多)
    eg:

    FileOutputStream fos = new FileOutputStream("1.txt");
            BufferedOutputStream out = new BufferedOutputStream(fos);
            out.write('a');
            out.flush();
            out.close();
    

    PrintStream :写8种基本数据类型,缓冲。
    RandomAccessFile:随机访问文件。

    字符流
    Reader/writer 字符流父类

    FileReader / FileWriter 文件字符流,节点流。

    BufferedReader / BufferedWrite(一般用Printwrite替代,采用默认编码方式) 缓冲流 过滤流。

    InputStreamReader / PrintWriter 桥转换,把字节流转换为字符流。
    在转换时指定编码方式。
    eg:

        FileOutputStream fos = new FileOutputStream("1.txt");
            BufferedOutputStream out = new BufferedOutputStream(fos);
            Writer wir = new OutputStreamWriter(out, "GBK");
            
            wir.write('s');
            wir.close();
    

    3.对象序列化
    对象序列化:将对象通过流传输
    ObjectOutputStream / ObjectInputStream
    只有实现了Serializable接口的对象才能初始化。不仅对象本身需要实现Serializable接口,对象属性也需要实现该接口。用transient修饰的属性不参与序列化。
    eg:对象XulieHuaTest

    package test;
    
    import java.io.Serializable;
    
    public class XulieHuaTest implements Serializable{
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        int age;
        String name;
        
        XulieHuaTest(int age,String name)
        {
            this.age=age;
            this.name = name;
        }
    
    }
    
    

    写入

    FileOutputStream s = new FileOutputStream("1.text");
    ObjectOutputStream os= new ObjectOutputStream(s);
    
    XulieHuaTest one1 = new XulieHuaTest(20, "ss");
    os.writeObject(one1);
    os.close();
    

    读取

    FileInputStream r = new FileInputStream("1.text");
    ObjectInputStream read = new ObjectInputStream(r);
    XulieHuaTest sHuaTest = (XulieHuaTest)read.readObject();
    System.out.println("age+"+sHuaTest.age+"+name+"+sHuaTest.name);
    read.close();
    

    4.异常处理
    java中的异常处理有两种
    1.throws 声明抛出 沿着调用链反向处理 属于消极处理。

    public void testException() throws IOException
    {
        //FileInputStream的构造函数会抛出FileNotFoundException
        FileInputStream fileIn = new FileInputStream("E:\\a.txt");
        
        int word;
        //read方法会抛出IOException
        while((word =  fileIn.read())!=-1) 
        {
            System.out.print((char)word);
        }
        //close方法会抛出IOException
        fileIn.clos
    }
    

    2.try...catch...finally 积极处理

    public static void main(String[] args){
            try {
                foo();
            }catch(ArithmeticException ae) {
                System.out.println("处理异常");
                ae.printStackTrace();
            }
    }
    public static void foo(){
            int a = 5/0;  //异常抛出点
            System.out.println("这是一个测试!!");  //////////////////////不会执行
    }
    

    方法覆盖,抛异常的子类不能比父类抛出更多的异常。

    相关文章

      网友评论

          本文标题:java基础知识总结(四)

          本文链接:https://www.haomeiwen.com/subject/rjqxrftx.html