IO

Runtime对象的exec()方法可以运行其他程序,并产生一个Process对象。Process类提供3个方法

getErrorStream() 获取子进程错误流   getInputStream() 获取子进程输入流  getOutputStream() 获取子进程输出流

    public static void main(String[] args) throws Exception {
        Process p = Runtime.getRuntime().exec("javac");
        BufferedReader bf = new BufferedReader(new InputStreamReader(p.getErrorStream()));
        String b = null;
        while ((b = bf.readLine()) != null) {
            System.out.println(b);
        }
        bf.close();
    }
View Code

RandomAccessFile  支持随机访问方式,既可以读,又可以写,如果想读写文件的一部分,应该用这个类

    public static void insert(String filename, int pos, String content) throws Exception {
        File tmp = File.createTempFile("tmp", null);
        tmp.deleteOnExit();
        
        RandomAccessFile raf = new RandomAccessFile(filename, "rw");
        FileInputStream tmpi = new FileInputStream(tmp);
        FileOutputStream tmpo = new FileOutputStream(tmp);
        
        int hasRead = 0;
        raf.seek(pos);
        byte[] buf = new byte[64];
        while ((hasRead = raf.read(buf)) > 0) {
            tmpo.write(buf, 0, hasRead);
        }
        raf.seek(pos);
        raf.write(content.getBytes());
        while ((hasRead = tmpi.read(buf)) > 0) {
            raf.write(buf, 0, hasRead);
        }
        raf.close();
        tmpi.close();
        tmpo.close();
    }
View Code

当一个可序列化的类有多个父类时,包括直接父类和间接父类,这些父类要么有无参构造器,要么也是可序列化的,如果父类不可序列化,只带无参构造器,父类定义的field不会序列化到二进制流中。

对象引用的序列化:如果类的field类型不是基本类型或String类型,而是引用类型,引用类必须可序列化,否则原类也不可序列化。

 1 新io  采用内存映射文件的方式来处理输入输出,新io将文件或文件的一段区域映射到内存,这样可以像访问内存一样访问文件。

channel对传统输入输出的模拟,新系统中所有数据都要通过channel,通过他的map方法可以将一块数据映射到内存。传统输入输出面向流,新io面向块

2 buffer 像一个数组,保存多个类型相同的数据1  capacity  最大数据容量   2 limit  后的内容不能读写 3 position  下一开始读写的位置

 读写过程   1 创建buffer  position为0,limit为capacity 2 写入数据时,position后移 , 写完后 position为0,limit为position  3 开始读 , 读完后 position变为0,limit为capacity ,和刚创建一样。

CharBuffer buff = CharBuffer.allocate(8);
        System.out.println(buff.capacity()); 8 
        System.out.println(buff.limit());  8
        System.out.println(buff.position()); 0
        
        buff.put('a');
        buff.put('b');
        buff.put('c');
        
        System.out.println(buff.position());3
        buff.flip();
        System.out.println(buff.limit());3
        System.out.println(buff.position());0
        
        System.out.println(buff.get());a
        
        buff.clear();
        System.out.println(buff.limit());8
        System.out.println(buff.position());0
        
        System.out.println(buff.get(2));c
View Code

3 channel类似与传统流对象,与传统流对象不同是, 1  可以直接将指定文件的全部或部分直接映射成buffer  2  程序不能直接访问channel中的数据,channel只能与buffer交互。 map将channel对应的部分或全部映射成bytebuffer  , read write 用于与buffer交互

        FileChannel inc = new FileInputStream("a.txt").getChannel();
        FileChannel outc = new FileOutputStream("c.txt").getChannel();
        MappedByteBuffer buff = inc.map(MapMode.READ_ONLY, 0, new File("a.txt").length());
        outc.write(buff);
        buff.clear();
View Code
        FileChannel f = new RandomAccessFile(new File("a.txt"), "rw").getChannel();
        MappedByteBuffer buff = f.map(MapMode.READ_ONLY, 0, new File("a.txt").length());
        f.position(new File("a.txt").length());
        f.write(buff);
View Code

 4 Charset  处理字节序列和字符序列之间的转换关系,还包含用于创建解码器和编码器的方法。

获得charset对象后,可以通过方法newDecoder, newEncoder方法分别返回charsetDecoder  和charsetEncoder对象,代表charset解码和编码器,通过decoder方法把bytebuffer字节序列转换成charbuffer字符序列,通过encoder将charbuffer将charbuffer或string转换成bytebuffer字节序列。

    public static void main(String[] args) throws Exception {
        Charset c = Charset.forName("GBK");
        CharsetEncoder newEncoder = c.newEncoder();
        CharsetDecoder newDecoder = c.newDecoder();
        CharBuffer buff = CharBuffer.allocate(8);
        buff.put("a");
        buff.put("sdfs");
        buff.flip();
        
        ByteBuffer bf = newEncoder.encode(buff);
        System.out.println(newDecoder.decode(bf));
    }
View Code

5 Java7 对io的改进     1 提供了全面的文件io和文件系统访问支持  2 基于异步channel的io

1  提供path接口  files,paths类 files 提供了文件复制,读取文件内容,写入文件内容的方法。

6 进程 :运行中的任务,具有一定独立功能,是系统进行资源分配和调度的独立单位。有3特性 : 1 独立性  有自己独立资源,有自己的地址空间,不允许访问其他进程地址空间  2 动态性 系统中活动的指令集合,有自己生命周期和各种不同状态,3 并发性 多进程在单处理器并发执行,之间不会相互影响。

线程是进程的组成部分,一个进程可以拥有多个线程,一个线程必须有一个符进程,线程拥有自己堆栈,程序计数器,局部变量,但不拥有系统资源,她与父进程其他线程共享进程的全部资源,编程简单。抢占式:当前运行的线程在任何时候都可能被挂起,以便另一个线程运行。

线程优点:1 进程不能共享内存,线程能共享内存    2 系统创建进程需要为进程重新分配内存,但创建线程代价小,效率高, 3 Java内置多线程功能支持,不是单纯地作为底层操作系统调度方式,简化多线程编程。

 7 使用Calleable和Future创建线程

public class JDBCTest{
    public static void main(String[] args) throws Exception {
        MyF m = new MyF();
        FutureTask<Integer> f = new FutureTask<>(m);
        for (int i = 0; i < 100; i++) {
            if (i == 20) {
                new Thread(f).start();
            }
        }
        System.out.println(f.get());
    }
}

class MyF implements Callable<Integer> {

    @Override
    public Integer call() throws Exception {
        // TODO Auto-generated method stub
        int i;
        for (i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
        return i;
    }
    
}
View Code

public class JDBCTest{
    public static void main(String[] args) throws Exception {
        Accout a = new Accout("d",1000);
        new DrawThread(a, 800).start();
        new DrawThread(a, 800).start();
    }
    
}
class DrawThread extends Thread {
    private Accout accout;
    private double money;
    public DrawThread(Accout accout, double money) {
        super();
        this.accout = accout;
        this.money = money;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        if (accout.getPrice() > money)  {
            System.out.println("success   " + money);
            
            
            accout.setPrice(accout.getPrice() - money);
            System.out.println("yu e" + accout.getPrice());
        } else {
            System.out.println("error");
        }
    }
}
class Accout {
    private String name;
    private double price;
    public Accout(String name, double price) {
        super();
        this.name = name;
        this.price = price;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    
}
View Code
public class JDBCTest{
    public static void main(String[] args) throws Exception {
        Accout a = new Accout("d",1000);
        new DrawThread(a, 800).start();
        new DrawThread(a, 800).start();
    }
    
}
class DrawThread extends Thread {
    private Accout accout;
    private double money;
    public DrawThread(Accout accout, double money) {
        super();
        this.accout = accout;
        this.money = money;
    }
    @Override
    public void run() {
        synchronized (accout) {
            // TODO Auto-generated method stub
            if (accout.getPrice() > money) {
                System.out.println("success   " + money);

                accout.setPrice(accout.getPrice() - money);
                System.out.println("yu e" + accout.getPrice());
            } else {
                System.out.println("error");
            }
        }
    }
}
class Accout {
    private String name;
    private double price;
    public Accout(String name, double price) {
        super();
        this.name = name;
        this.price = price;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    
}
View Code

线程安全的类, 1 类的对象可以被多个线程安全访问,  2 每个线程调用对象的方法后会得到正确结果,并且对象状态保持合理状态。

public class JDBCTest{
    public static void main(String[] args) throws Exception {
        Accout a = new Accout("d",1000);
        new DrawThread(a, 800).start();
        new DrawThread(a, 800).start();
    }
    
}
class DrawThread extends Thread {
    private Accout accout;
    private double money;
    public DrawThread(Accout accout, double money) {
        super();
        this.accout = accout;
        this.money = money;
    }
    @Override
    public void run() {
            // TODO Auto-generated method stub
        accout.draw(money);
    }
}
class Accout {
    private String name;
    private double price;
    public Accout(String name, double price) {
        super();
        this.name = name;
        this.price = price;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public synchronized void draw(double money) {
        if (price > money) {
            System.out.println("success   " + money);

            price -= money;
            System.out.println("yu e" + price);
        } else {
            System.out.println("error");
        }
    }
}
View Code

当两个线程相互等待对方释放同步监视器时,就会发生死锁

public class JDBCTest implements Runnable{
    
    private A a = new A();
    private B b = new B();
    
    public void init() {
        Thread.currentThread().setName("zhu");
        a.info(b);
        System.out.println("after zhu");
    }
    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        Thread.currentThread().setName("fu");
        b.info(a);
        System.out.println("after fu");
    }
    public static void main(String[] args) throws Exception {
        JDBCTest t = new JDBCTest();
        new Thread(t).start();
        t.init();
    }
    
}
class A {
    public synchronized void info(B b) {
        System.out.println(Thread.currentThread().getName() + "进入实例A的info方法");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "调用B的last方法");
        b.last();
    }
    public synchronized void last() {
        System.out.println(Thread.currentThread().getName() + "进入实例B的last方法");
    }
}


class B{
    public synchronized void info(A a) {
        System.out.println(Thread.currentThread().getName() + "进入实例B的info方法");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "调用a的last方法");
        a.last();
    }
    public synchronized void last() {
        System.out.println(Thread.currentThread().getName() + "进入实例B的last方法");
    }
}
View Code

 ThreadLocal  线程局部变量,为每一个使用变量的线程都提供一个变量值的副本,使每一个线程都可以独立改变自己的副本而不会和其他线程冲突,。当多个线程之间需要共享资源,达到线程之间通信功能,使用同步机制,如果仅仅需要隔离多个线程间共享冲突可以使用Threadlocal

public class JDBCTest extends Thread{
    private Account a;
    
    public JDBCTest(Account a, String name) {
        super(name);
        this.a = a;
    }
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            if (i == 6) {
                a.setName(getName() + "  " + i);
            }
            System.out.println(a.getName() + "  " + i);
        }
    }
    public static void main(String[] args) throws Exception {
        Account a = new Account();
        new JDBCTest(a, "jia").start();;
         new JDBCTest(a, "yi").start();
    }
    
}
class Account {
    private ThreadLocal<String> name = new ThreadLocal<>();

    public String getName() {
        return name.get();
    }

    public void setName(String name) {
        this.name.set(name);
    }
    
}
View Code

 

posted on 2017-09-23 15:43  wheleetcode  阅读(162)  评论(0编辑  收藏  举报