线程_IO串讲

Posted 陈鹏烨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程_IO串讲相关的知识,希望对你有一定的参考价值。

07-03-01 线程_IO串讲

 

进程是一套顺序执行的指令。

同时开辟并行执行序列即多线程          run() 结束,线程就结束

JVM就是一个进程,在JVM中分出线程

进程数据空间独立;线程数据空间共享, 线程间通信更容易

分配的方式不如线程好,能充分使用CPU的资源。 共享数据就要加锁、解锁,会降低效率。

 

OS 时分共享操作系统 实时操作系统

时分共享操作系统    时间片    调度系统把每个时间片分给多个进程   性能调优是根据时间片划分, 时间片会影响整个操作系统。

 

为了让某些工作并行,在进程主线程中开辟多个线程,这就是线程的机制。

 

 

我们关心的是被线程共享的数据,主要看synchronized加在何处。往往不加在线程里面,而是在共享的对象上。

 

只有运行状态的线程才有机会执行代码!

只有等到所有线程终止,进程才结束!

当一个对象分配给某线程锁标记时,其它线程不能访问同步方法,但能访问非同步方法!

 

起线程的两种方式:1、继承Thread,覆盖run()方法,用start()启动

                  2、实现Runnable接口,用来构造线程对象。(线程对象不是线程,但代表一个线程)

例子 ProducerConsumer.java

每一个对象都有一个互斥锁标记(monitor),这个锁标记是准备分配给线程的,且只能分配给一个线程

用法一:

synchronized(o){

     原子操作代码块

}

哪个线程能拿到o的锁标记,哪个线程才能进入这个同步代码块,用完后释放锁标记

未加同步可能造成数据不一致和数据不完整的缺陷。

 

用法二:

public synchronized void method(){ …}      

等价于:

Public void method(){

           Synchronized(this){...}

}    

在整个方法中,对this加锁。

 

l         构造方法   不能同步,因为还没有当前对象

l         抽象方法   也不能同步,因为子类覆盖方法后可以是非同步方法,父类就有多余的话。

 

每一个对象都有一个锁池,装的是等待该对象锁标记的线程。

 

一个线程可以同时拥有多个对象的锁标记

     synchronized(o1){                //同步代码块是可以嵌套的

           synchronized(o2){

           }

     }

 

当一个线程阻塞在A对象的锁池里的时候,不会释放其所拥有的其他对象的锁标记

 

每个线程不释放自己拥有的资源,却申请别的线程的资源,就可能造成死锁问题

 

线程t1:   o.wait()  

前提:  必须在对o加锁的同步代码块里

1.  t1会释放其所拥有的所有锁标记

2.  t1会进入o的等待队列

 

线程t2: o.notify() / o.notifyAll()

前提:必须在对o加锁的同步代码块里

t2会从o的等待队列中释放一个线程/所有线程

 

推荐:尽量用notifyAll取代notify, 因为由OS决定只释放哪个线程

 

 

wait() sleep()的联系和区别:

1. wait()是从Object继承下来的方法,而sleep()Thread中的静态方法

2. wait() sleep()都要阻塞运行,释放CPU资源

3. wait()要释放锁; sleep()不释放锁

wait()方法被调用时会解除锁定,但是我们能使用它的地方只是在一个同步方法或代码块内。

 

新思路:必要时可利用Object中的 锁标记锁池等待队列 用其wait() / notify() 方法,

       自己制造临界资源来进行线程间通讯。

      (参考字母数字交叉打印的例子TestNumberCharPrint.java

       其中注意o.notifyAll() o.wait() 的调用顺序,还要注意边界问题,体现在最后要来一个判断if(c!=’Z’)  o.wait(); 进而让程序正常结束。

 

 

I/O

一、流的分类

  1 数据传输方向划分:输入流和输出流

I  输入流      JVM ——>数据源      InputXXX

O  输出流     JVM <—— 数据源      OutputXXX

 

2 数据单位划分:字节流和字符流

       字节流   一次传输一个字节

       字符流   一次传输一个字符

字节流类:

抽象父类: InputStream     字节输入流 xxxInputStream

实现类:

                     BufferedInputStream 缓冲流——过滤流   

                     ByteArrayInputStream 字节数组流——节点流

                     DataInputStream    处理Java标准数据流——过滤流

                     FileInputStream 处理文件IO流——节点流

            FilterInputStream 实现过滤流——字节过滤流父类

                     PipedInputStream 管道流,在两个线程交换数据

                     PrintStream  包含print() println()

                     RandomAccessFile 只支持随机访问文件,用于定位的seek()方法。 了解即可

                     SequenceInputStream 在合并两个文件是较好用(顺序流)

     字符流:

可以解决字符编码问题

ReaderWriter (字符流类,所有字符流的父类型)

3)按流的功能划分:

节点流 / 过滤流(使用装饰模式

        节点流用来传输数据。

     过滤流用来封装节点流或者其他过滤流,从而给节点流或其他的过滤流增加功能。

            首先要通过构造得到InputStream OutputStream 对象

            关闭流时只需关最外层的流。

            注意使用out.flush()来清空缓冲区。 out.close()默认调用flush

I/O本身是抽象的,当 目的确定了I/O就不抽象了。

 

u       构造方法的记忆方法:

(1)、代表的事物,构造方法就加

例如  FileInputStream   File代表源的事物,构造方法就加源

      FeInputStreamil(File file)

(2)、代表功能,构造方法就放InputStream OutputStream

例如  ObjectInputStream  Object代表功能,构造方法就放InputStream

      DataInputStream   Data分为intbytechar8种简单类型外加String

构造方法放InputStream

      PushbackInputStream  Pushback代表具有缓冲的功能,所以构造方法放InputStream

InputStream, OutputStream为抽象的,子类型不抽象

建议主要记Read / Write 方法即可,其它的掌握规律

比如看到Data就要想到会装不同类型数据: intbytechar …

 

 

InputStream

所有字节输入流的父类,如:FileInputStream, Ob jectInputStream,PipedInputStrean

三个基本的read()方法

   A.  int read() 从流里读出的一个字节或者返回-1;

以上是关于线程_IO串讲的主要内容,如果未能解决你的问题,请参考以下文章

0607pm克隆&引用类&加载类&面向对象串讲&函数重载

java内存流:java.io.ByteArrayInputStreamjava.io.ByteArrayOutputStreamjava.io.CharArrayReaderjava.io(代码片段

java缓冲字符字节输入输出流:java.io.BufferedReaderjava.io.BufferedWriterjava.io.BufferedInputStreamjava.io.(代码片段

大数据技术之_29_MySQL 高級面试重点串讲_02_Mysql 简介+Linux 版的安装+逻辑架构介绍+性能优化+性能分析+查询截取分析+分区分库分表简介+锁机制+主从复制

稳定性 耗时 监控原因分析-- dubbo rpc 框架 的线程池,io 连接模型. 客户端,服务端

python_day10 多线程 协程 IO模型