黑马程序员_io流详解
多线程总结:
1,进程和线程的概念。
|--进程:正在运行中的程序
|--线程:进程中的一个执行单元,负责进程中程序执行的控制单元
2,jvm中的多线程体现。
|--主线程,垃圾回收线程,自定义线程。以及他们运行的代码的位置。
|--主线程:负责执行main函数中的内容
|—垃圾回收线程:负责垃圾回收器运行的线程
3,什么时候使用多线程,多线程的好处是什么?创建线程的目的?
|--当需要多部分代码同时执行的时候,可以使用多线程。
|--多线程可以把任务分块执行,分块后可以同时进行而不用等待,这样效率更高
|--目的:为了开启一个单独的执行路径,运行指定的代码
4,创建线程的两种方式。
|--继承Thread
|--步骤1 定义类继承Thread类
2 覆盖Thread类中的run方法
3 创建Thread类的子类对象创建线程对象
4 调用线程中的start方法开启线程
|--实现Runnable
|--步骤1 定义一个类实现Runnable接口
2 覆盖Runnable接口中的run方法
3 创建该接口的子类对象
4 通过Thread类进行线程的创建,并将Runnable接口的子类对象作为Thread类
的构造函数的实参进行传递
5 调用Thread类中的start方法开启线程
|--两种方式的区别?
通过Runnable接口可以降低和Thread对象的耦合性
5,线程的5种状态。
对于执行资格和执行权在状态中的具体特点。
|--被创建:
|--运行:具备cpu的执行资格和执行权
|--冻结:释放了cpu的执行资格和执行权
|--临时阻塞:具备cpu的执行资格不具备cpu的执行权
|--消亡:
6,线程的安全问题。
|--安全问题的原因:一个线程在执行多条操作共享数据的过程中,其他线程参与了运算
|--解决的思想:线程任务中有没有共享数据,该共享数据是否被多条语句惭怍
|--解决的体现:synchronized
保证一个线程在执行多条操作共享数据的语句时,其他线程不得参与执行,
|--同步的前提:但是加上同步还出现安全问题,就需要用前提来思考。
保证在同步中有多个线程,保证多个线程在同步中使用的是同一个锁
|--同步的两种表现方法和区别:同步代码块和同步函数
|--同步的好处和弊端:好处是解决了多线程的安全问题,弊端是会降低性能
|--单例的懒汉式。在被多线程并发访问时,就会出现多线程的安全问题
解决办法 改用同步代码块,可以通过双重判断的形式来完成这个过程
class Single
{
private static Single s = null;
private Single(){}
public static Single getInstance()
{
if(s==null)
{
synchronized(Single.class)
{
if(s==null)
s = new Single();
}
}
return s;
}
}
|--死锁。
常见的死锁情况就是同步嵌套,同步里还有同步,两个同步用的是不一样的锁
7,线程间的通信。等待/唤醒机制。
|--概念:多个线程,不同任务,处理同一资源。
生产者消费者问题,
|--等待唤醒机制。使用了锁上的 wait notify notifyAll.
wait()等待,将正在执行的线程释放其执行资格和执行权,并存储到线程池中
notify()唤醒 唤醒线程池中被wait的线程,一次唤醒一个,而且是任意的
notifyAll()唤醒全部,可以将线程池中的所有wait线程都唤醒
|--生产者/消费者的问题。并多生产和多消费的问题。 while判断标记。用notifyAll唤醒对方。
|--JDK1.5以后出现了更好的方案
Lock接口替代了synchronized
Condition接口替代了Object中的监视方法,并将监视器方法封装成了Condition
和以前不同的是,以前一个锁上只能有一组监视器方法。现在,一个Lock锁上可以多组监视器方法对象。
可以实现一组负责生产者,一组负责消费者。
|--wait和sleep的区别。
两种方法都可以让线程处于冻结状态
sleep()必须指定时间,wait可以指定时间,也可以不指定
sleep会释放执行权,不会释放锁,wait会释放执行权和锁
8,停止线程的方式。
|--原理:当线程没有了要运行的代码线程就结束了,以为这任务结束,县城小事
|--表现:--中断。
Thread类中有个interrupt方法,可以将线程的冻结状态清除,让线程恢复到执行资格
9,线程常见的一些方法。
|--setDaemon()将其中的线程标记为后台线程,后台线程就对前台线程有一定的依赖性
如t2.setDaemon(true)
|--join();当主线程遇到有join方法的线程时 主线程释放执行权和执行资格,等待有join方法 的线程执行
|--优先级:线程抢到cpu的频率高与低
|--yield();临时暂停,释放执行权
|--在开发时,可以使用匿名内部类来完成局部的路径开辟。
class
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
*/