线程
2019-04-21 / JAVA / 924 次围观 / 0 次吐槽 /线程概述
什么是线程
线程是程序执行的一条路径, 一个进程中可以包含多条线程
一个应用程序可以理解成就是一个进程
多线程并发执行可以提高程序的效率, 可以同时完成多项工作
并行和并发的区别
并行就是两个任务同时运行,就是甲任务进行的同时,乙任务也在进行。(需要多核CPU)
并发是指两个任务都请求运行,而处理器只能按受一个任务,就把这两个任务安排轮流进行,由于间时间隔较短,使人感觉两个任务都在运行
Java程序运行原理
Java命令会启动java虚拟机(JVM),等于启动了一个应用程序,也就是启动了一个进程。
该进程会自动启动一个 “主线程” ,然后主线程去调用某个类的 main 方法
一个应用程序有且只有一个主线程,程序员不能New主线程,可以New子线程。
JVM启动的是多线程吗?
JVM启动至少启动了垃圾回收线程和主线程,所以是多线程的。
main方法的代码执行的位置就是在主线程(路径)
一个进程有多个线程
finalize()这个方法在子线程(垃圾回收线程)执行
Java中线程的实现方式
方式一、继承Thread
使用步骤:
1.定义类继承Thread
2.重写run方法
3.把新线程要做的事写在run方法中
4.创建线程对象
5.开启新线程 start(), 内部会自动执行run方法
方式二、实现Runnable接口
实现步骤:
1.定义类实现Runnable接口
2.实现run方法
3.把新线程要做的事写在run方法中
4.创建自定义的Runnable的子类对象,创建Thread对象传入Runnable
5.调用start()开启新线程, 内部会自动调用Runnable的run()方法
两种方式的区别
区别:
继承Thread : 由于子类重写了Thread类的run(), 当调用start()时直接找子类的run()方法
实现Runnable : 构造函数中传入了Runnable的引用, 有个成员变量记住了它, 调用run()方法时内部判断成员变量Runnable的引用是否为空。
继承Thread
好处是:可以直接使用Thread类中的方法,代码简单
弊端是:如果已经有了父类,就不能用这种方法
实现Runnable接口
好处是:即使自己定义的线程类有了父类也没关系,因为有了父类也可以实现接口,代码更灵活
弊端是:不能直接使用Thread中的方法,需要先获取到线程对象后,才能得到Thread的方法,代码复杂
匿名内部类实现线程的两种方式
获取线程名字和设置名字
通过Thread的getName()方法获取线程对象的名字
通过setName(String)方法可以设置线程对象的名字
通过构造函数可以传入String类型的名字
每个线程系统都会默认分配个名字,主线程:main,子线程thread-0 ....
获取当前线程的对象
Thread.currentThread()方法用于获取当前线程对象
在不同的方法中,获取的线程对象名称是有可能不一样的
在main中获取的是主线程对象
在子线程的run方法中获取的是子线程对象
线程的其它方法
线程休眠
Thread.sleep(毫秒), 控制当前线程休眠若干毫秒
1秒= 1000毫秒
1秒 = 1000毫秒* 1000微妙 * 1000纳秒(1000000000 )
守护线程
setDaemon(), 设置一个线程为守护线程, 该线程不会单独执行, 当其他非守护线程都执行结束后, 自动退出
特点:A线程守护另B线程,B线程退出,A线程也退出
加入线程
join(), 当前线程暂停, 等待指定的线程执行结束后, 当前线程再继续
join(int), 可以等待指定的毫秒之后继续
线程让出
yield() 让出cpu
线程优先级
setPriority()设置线程的优先级
默认优先级是5,最小优先级1,最高优先级10
可以设置2,3,4
Thread里面有静态常量
开发几乎不用,了解
线程与同步
什么是同步
同步就是加锁,不让其它人访问
synchronized指的就是同步的意思
什么情况下需要同步
当多线程并发, 有多段代码同时执行时, 我们希望某一段代码执行的过程中CPU不要切换到其他线程工作. 这时就需要同步.
如果两段代码是同步的, 那么同一时间只能执行一段, 在一段代码没执行结束之前, 不会执行另外一段代码.
同步代码块
使用synchronized关键字加上一个锁对象来定义一段代码, 这就叫同步代码块
多个同步代码块如果使用相同的锁对象, 那么他们就是同步的
同步方法
使用synchronized关键字修饰一个方法, 该方法中所有的代码都是同步的
非静态同步函数的锁是:this
静态同步函数的锁是:字节码对象(xx.class)
锁的总结
1.锁问题:
同步中,锁最好同一个对象,如果不是同一对象,还是会有线程安全问题
锁:this,代表当前对象
锁:如果 new 对象,就不是同一把锁
锁:字节码对象 String.class,内存中,只有一个字节码对象
开发中:一般都是this
2.在方法内部声明synchronized的就是 “同步代码块”
3.在声明方法的时候,添加 synchronized,就是同步方法
如果是非静态方法,锁就是this
如果是静态方法,锁就当前类的字节码对象
//TicketTask.class
public static synchronized void test1(){}
4.同步使用的建议:
同步加锁的时候,尽量让锁住的代码范围小一点,这样可以让其它线程等待时间少一点,性能高
死锁
死锁就是多个线程锁住不释放
线程的五种状态
新建,就绪,运行,阻塞,死亡
回顾线程安全的类
Vector,StringBuffer,Hashtable
Vector是线程安全的,ArrayList是线程不安全的
StringBuffer是线程安全的,StringBuilder是线程不安全的
Hashtable是线程安全的,HashMap是线程不安全的
- 上一篇:Properties类
- 下一篇:单例设计模式
Powered By Cheug's Blog
Copyright Cheug Rights Reserved.