黑马程序员_java学习笔记 6.多线程
来源:互联网 发布:计算机技术与软件 证书 编辑:程序博客网 时间:2024/05/29 10:08
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
多线程
一、什么是多线程
1、线程的定义
进程:是一个正在执行的程序,每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。
线程:就是进程中的一个独立的控制单元, 线程在控制着进程的执行,一个进程中至少有一个线程。该进程中至少有一个线程,负责java程序的执行。而且这个线程运行的代码存在于main方法中。该线程称之为主线程。
2、多线程的分类
用户线程:用户产生的线程
精灵线程:为用户线程提供服务的线程,通常在后台运行。
Java虚拟机至少有一个精灵线程,即垃圾收集线程。垃圾收集线程只在系统空闲时运行,它是一个低优先级线程。
Java VM 启动时会有一个进程java.exe
扩展:其实更细节说明jvm,jvm启动的不止一个线程,还有垃圾回收机制的线程。
3、多线程的优势
二、多线程的实现方式
1 声明一个 Thread 类的子类,并覆盖 run() 方法。
- class Mythread extends Thread
- {
- public void run( )
- {
- }
- }
2 声明一个实现 Runnable 接口的类,并实现 run() 方法
- class Mythread implements Runnable
- {
- public void run( )
- {
- }
- }
3、两种方式的区别
区别一:
由于子类重写了Thread类的run(), 当调用start()时, 直接找子类的run()方法
构造函数中传入了Runnable的引用, 成员变量记住了它, start()调用run()方法时内部判断成员变量Runnable是否为空, 不为空则执行Runnable的run()
区别二:
继承Thread只能是单继承,如果自己定义的线程类已经有了父类,就不能再继承了
实现Runnable接口可以多实现,即使自己定义线程类已经有父类可以实现Runnable接口
4.优缺点
继承Thread的好处是:可以直接使用Thread类中的方法,代码简单。 弊端是:如果已经有了父类,就不能用这种方法
实现Runnable接口的好处是:即使自己定义的线程类有了父类也没关系,因为有了父类也可以实现接口。而且接口是可以多实现的。 弊端是:不能直接使用Thread中的方法。需要先获取到线程对象后,才能得到Thread的方法,代码复杂
三、多线程的安全问题
1、
解决办法:
2、
Java对于多线程的安全问题提供了专业的解决方式,
就是同步代码块。
synchronized(对象)
{
}
对象如同锁,持有锁的线程可以在同步中执行。
没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。
3、
同步的前提:
1、必须要有两个或两个以上的线程。
2、必须是多个线程使用同一个锁。
必须保证同步中只能有一个线程在运行。
好处:解决了多线程的安全问题。
弊端:多个线程需要判断锁,较为消耗资源。
同步函数用的是哪一个锁呢?
函数需要被对象调用,那么函数都有一个所属对象引用,就是this。
所以同步函数使用的锁是this。
如果同步函数被静态修饰后,使用的锁是什么呢?
通过验证,发现不再是this。因为静态方法中也不可以定义this。
静态进入内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象。
类名.class
静态的同步方法,使用的锁是该方法所在类的字节码文件对象。也就是 类名.class
4、死锁
所谓死锁:是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象:死锁。”
四、设计模式
单例设计模式之饿汉式和懒汉式
1、饿汉式:
- <pre name="code" class="java">class Single
- {
- //私有化对象
- private static final Single s=new Single();
- private Single(){}
- //提供一个获取对象的方法
- public static Single getInstance()
- {
- return s;
- }
- }
2、懒汉式:
- <pre name="code" class="java">class Single
- {
- //定义一个空对象
- private static Single s=null;
- private Single(){}
- //定义get方法
- public static Single getInstance()
- {
- //定义判断条件
- if(s==null)
- {
- //判断锁
- synchronized(Single.class)
- {
- if(s==null)
- s=new Single();//创建对象
- }
- }
- return s;//返回对象
- }
- }
懒汉式特点是延迟加载,但是多线程访问时会出现安全问题,这时加锁可以解决安全问题,但是会让程序低效。用双重判断的方式,可以解决效率问题
五、线程之间的通信
1、 如果希望线程等待,就调用wait()
如果希望唤醒等待的线程,就调用notify();
这两个方法必须在同步代码中执行, 并且使用同步锁对象来调用
2、多个线程通信的问题
notify()方法是随机唤醒一个线程(优先唤醒先等待的线程)
notifyAll()方法是唤醒所有线程
JDK1.5之前无法唤醒指定的一个线程
如果多个线程之间通信, 需要使用notifyAll()通知所有线程, 用while来反复判断条件
1.5中提供了多线程升级解决方案:
将同步Synchronized替换成现实Lock操作,
将object中wait,notify,notifyAll替换成了Condition对象
该对象可以通过Lock锁进行获取 lock.newCondition()
3、停止线程:
run方法结束,只有控制循环,就可以让run方法结束。
- 黑马程序员_java学习笔记 6.多线程
- 黑马程序员_java多线程学习笔记
- 黑马程序员_java多线程学习笔记
- 黑马程序员_java 多线程笔记
- 黑马程序员_java多线程学习
- 黑马程序员_Java多线程学习
- 黑马程序员_java自学学习笔记(六)----多线程
- 黑马程序员_java基础_多线程学习笔记
- 黑马程序员_java基础学习笔记10_多线程
- 黑马程序员_java学习笔记
- 黑马程序员_java多线程笔记Part I
- 黑马程序员_java基础笔记(04)...多线程
- 黑马程序员_java多线程学习总结
- 黑马程序员_java多线程
- 黑马程序员_JAVA多线程
- 黑马程序员_java多线程
- 黑马程序员_java多线程
- 黑马程序员_java多线程
- 导入即可SpingMVC+MyBatis简单权限管理系统,带数据库
- 拖放转换 批量转换 xls 2 txt
- 初识html总结
- html js 输入日期输出星期
- 设置QTableWidget的左上角CornerWidget的文字(一)
- 黑马程序员_java学习笔记 6.多线程
- iOS9 app显示英文
- 11-EMM Procedure 1. Initial Attach Part2
- iOS项目发布流程
- StackEdit Windows本地服务器搭建
- 建造者模式
- oracle 12c rac dbca建库,提示无法访问+DATA磁盘组
- Error:(27, 42) 错误: <匿名com.jeff.networktest.MainActivity$1>不是抽象的, 并且未覆盖Handler中的抽象方法publish(LogRecord
- 222 Count Complete Tree Nodes