JUC并发编程-线程基础知识
并发相关Java包
- 涉及到的
包
内容java.util.concurrent
java.util.concurrent.atomic
java.util.concurrent.locks
start线程解读
初始程序
1 |
|
1 |
|
1 |
|
native
调用了本地方法,我们可以通过下载官网OpenJDK查看其源码
thread.c
java线程是通过start的方法启动执行的,主要内容在native方法start0中
Openjdk的写JNI一般是一一对应的,
Thread.java
对应的就是Thread.c
start0
其实就是JVM_StartThread
。此时查看源代码可以看到在jvm.h中找到了声明,jvm.cpp中有实现。
jvm.cpp
thread.cpp
- 终于在这里调用了操作系统的线程启动,
os::start_thread(thread);
- 终于在这里调用了操作系统的线程启动,
Java多线程相关概念
1把锁
2个并(并发和并行)
①并发
是在同一实体上的多个事件,是在同一台处理器上“同时”处理多个任务,同一时刻,其实是只有一个事件在发生。
②并行
是在不同实体上的多个事件,是在多台处理器上同时处理多个任务,同一时刻,大家都真的在做事情,你做你的,我做我的
并发VS并行
3个程(进程 线程 管程)
- 通过上面start线程的案例,其实进程线程都来源于操作系统。
①进程
- 系统中运行的一个应用程序就是一个进程,每一个进程都有它自己的内存空间和系统资源。
- 进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元
②线程
- 也被称为轻量级进程,在同一个进程内基本会有1一个或多个线程,是大多数操作系统进行调度的基本单元。
③管程
- Monitor(监视器),也就是我们平时说的锁
- Monitor其实是一种同步机制,他的义务是保证(同一时间)只有一个线程可以访问被保护的数据和代码。
- JVM中同步是基于进入和退出监视器对象(Monitor,管程对象)来实现的,每个对象实例都会有一个Monitor对象,
- Monitor对象会和Java对象一同创建并销毁,它底层是由C++语言来实现的。
进程VS线程
进程和线程的最大不同在于进程基本上是独立的,而线程不一定,线程共享方法区和堆,线程私有栈、本地方法栈和程序计数器
用户线程和守护线程
Java线程分为用户线程和守护线程
- 线程的daemon属性为
- true表示是守护线程
- false表示是用户线程。
用户线程
是系统的工作线程,它会完成这个程序需要完成的业务操作
守护线程
是一种特殊的线程,为其他线程服务的,在后台默默地完成一些系统性的服务,比如垃圾回收线程。
总结
1 |
|
- 两种情况
- 未加
t1.setDaemon(true);
,默认是用户线程,他会继续运行,所以灯亮着 - 加了
t1.setDaemon(true);
是守护线程,当用户线程main方法结束后自动退出了
- 未加
- 守护线程作为一个服务线程,没有服务对象就没有必要继续运行了,如果用户线程全部结束了,意味着程序需要完成的业务操作已经结束了,系统可退出了。假如当系统只剩下守护线程的时候,java虚拟机会自动退出。
- setDaemon(true)方法必须在start()之前设置,否则报IIIegalThreadStateException异常
多线程的实现方式
继承Thread
1 |
|
实现Runnable接口
1 |
|
两种实现多线程方式的区别
(1).查看源码
a.继承Thread:由于子类重写了Thread类的run(),当调用start()时,直接找子类的run()方法
b.实现Runnable:构造函数中传入了Runnable的引用,成员变量记住了它,start()调用run()方法时内部判断成员变量Runnable的引用是否为空,不为空编译时看的是 Runnable的run(),运行时执行的是子类的run()方法
(2).继承Thread
a.好处是:可以直接使用Thread类中的方法,代码简单
b.弊端是:如果已经有了父类,就不能用这种方法
(3).实现Runnable接口
a.好处是:即使自己定义的线程类有了父类也没有关系,因为有了父类可以实现接口,而且接口可以多现实的
b.弊端是:不能直接使用Thread中的方法需要先获取到线程对象后,才能得到Thread的方法,代码复杂
Thread.activeCount( )
在IDEA中Thread.activeCount()=2,除了main方法的主线程外还有,还多了一个预期外的Monitor Ctrl-Break线程
1 |
|
在ECLIPSE中得到的结果是1
TimeUnit类
TimeUnit是java.util.concurrent包下面的一个类,TimeUnit提供了可读性更好的线程暂停操作,通常用来替换Thread.sleep( ) 底层实现还是使用的Thread.sleep( )
字段 | 描述 |
---|---|
SECONDS | 停顿3秒 |
MINUTES | 停顿3分钟 |
HOURS | 停顿3小时 |
DAYS | 停顿三天 |
1 |
|