java多线程---线程的通信、生产者与消费者模式

一、重点知识

isDaemon 判断是否为守护线程。

run方法是不能用synchronized修饰,他是继承来的,不能改变其结构,而且,如果run方法加了synchronized,就变成单线程了,就没有并发了。

只要不是静态的同步方法,同步方法默认的同步监视器就是this。

静态的同步方法的同步监视器为类.class

wait方法如果不是同步监视器去调用的话会报IllegalMonitorStateException异常

如果没有线程处于wait状态,调用notify此时是一个空唤醒

stringBuffer中的同步方法,都是非静态的,因为共用一个this锁就可以了,线程进去调用他的一个方法时就不能另一个线程调用它的其他方法,因为他有同步锁,且都是this。

等待队列用来存储休眠线程

java中的锁池和等待池

https://blog.csdn.net/emailed/article/details/4689220

锁池只是一个状态,并不是一个容器

等待队列是不消耗cpu资源的,因为他不需要查看是否时间到,wait的线程是不能自己苏醒的

threadlocal  存储的变量是线程分离的,里面只能存储一个值,线程一对这个变量进行的操作,其他线程是不会获取这个变量的

用处,用这个变量就不会造成数据共享了,也不会有线程安全问题了

底层用的是map集合

wait()必须用在snyoized内

lock中唤醒时唤醒的是等待时间最长的

condition调用对应的休眠与唤醒必须用在对应的lock锁内

线程组

group.interrput();给线程设置一个终止标志

对应方法

thread.isintreeput();//判断是否可以终止

创建线程池

newCachedThreadPool  不固定线程的数量

newFixedThreadPool (10)固定线程的数量

read读取的是byet返回的却是int,是应为一个中文两个字节,返回byet的话有可能为负数,可能提前导致读取结束,所以要用int

以后流中数组最好用8192  8kb

reader读取返回int的原因是为了便于判断

字符流里面也有一个缓冲区,读取字符,字符一开使是存储到缓冲区里,直到缓冲区存满,或者流关闭时数据才会被写出到文件中,因为这两种方式里调用了flush方法,把数据刷新出去

最好用类.class对象去当锁,因为每个类Class实例,内存中只有一个

二、重点问题

关于线程通信中wait放在while中还是if中的问题

线程通信中判断临界值条件一般用while而不用if 因为while可以保证不会因为异常而导致结束wait状态,if如果出现异常会结束等待状态执行下面的代码,这样就达不到我们的目的了。

三、课堂知识

3.1、同步方法

同步代码块:使用synchronized关键字包裹了一块代码,让这块代码同步执行。就是每次只能一个线程来执行。

同步方法:使用synchronized关键字修饰一个方法,这个方法同步执行。就是每次只能一个线程来执行。

普通的方法:对象调用。锁定的对象,就是this对象。

静态的方法:类调用。锁定的对象,就是类名.class

同步的原理:利用对象的互斥锁。

每个线程来访问,只能有一个线程进入执行,第一个动作锁对象(上锁)。来保证其他线程不能进入执行。等到该线程结束这个同步代码块或者同步方法,释放锁对象(开锁),才允许其他的线程来访问。

有同步方法,线程安全的类:

StringBuffer

Vector

HashTable

Collections,集合的工具类

3.2、线程之间的通信

线程之间的通信:wait(),notify(),notifyAll()

wait()——>让线程进入阻塞状态,暂停执行。一直阻塞

notify()——>唤醒线程,wait()住的线程,被唤醒。如果多个线程wait()了,唤醒其中的一个。

notifyAll()——>唤醒所有。

语法要求:必须在同步中,由同步的锁对象来调用。否则java.lang.IllegalMonitorStateException异常。

3.3、生产者消费者模型:

生产者(线程t1)负责生产产品,存入容器中(固定容量),消费者(线程t2)从容器中获取产品消费掉。

容器:

    生产者:持有资源,生产产品,存入容器中

    消费者:持有资源,消费掉产品。

容器满了:最多装有限个产品

    生产者:持有资源,暂停执行——直到容器还能继续装。

        锁对象.wait()——>会让线程进入阻塞状态。暂停执行。notify(),notifyAll()

    消费者:持有资源,直接消费。。


容器空了:最少0个。

    生产者:持有资源,生产,存入。。

    消费者:持有资源,暂停执行——直到容器中有产品

        锁对象.wait()——>会让线程进入阻塞状态。暂停执行。notify(),notifyAll()


3.4、wait()和sleep()方法的区别:

1、出处不同:

sleep()方法是Thread类中定义的。

wait()方法是Object类中定义的。

2、解除阻塞的方式不同

sleep()是时间到,自己醒。

wait()方法等待被唤醒:notify(),或者是notifyAll()

3、对锁资源的释放情况

sleep(),不释放,抱着不撒手

wait(),释放

你可能感兴趣的:(java多线程---线程的通信、生产者与消费者模式)