标签:判断 blank 处理 进程 弱引用 操作系统 单位 必须 结束
CPU核心数和线程数的关系
核心数:线程数=1:1 ;使用了超线程技术后---> 1:2
CPU时间片轮转机制
又称RR调度,会导致上下文切换
什么是进程和线程
进程:程序运行资源分配的最小单位,进程内部有多个线程,会共享这个进程的资源
线程:CPU调度的最小单位,必须依赖进程而存在。
澄清并行和并发
并行:同一时刻,可以同时处理事情的能力
并发:与单位时间相关,在单位时间内可以处理事情的能力
高并发编程的意义、好处和注意事项
好处:充分利用cpu的资源、加快用户响应的时间,程序模块化,异步化
问题:
线程共享资源,存在冲突;
容易导致死锁;
启用太多的线程,就有搞垮机器的可能
查看 JVM自启动线程
Attach Listener :线程是负责接收到外部的命令,而对该命令进行执行的并且吧结果返回给发送者。通常我们会用一些命令去要求jvm给我们一些反馈信息,如:java -version、jmap、jstack等等。如果该线程在jvm启动的时候没有初始化,那么,则会在用户第一次执行jvm命令时,得到启动。
signal dispather: 前面我们提到第一个Attach Listener线程的职责是接收外部jvm命令,当命令接收成功后,会交给signal dispather线程去进行分发到各个不同的模块处理命令,并且返回处理结果。signal dispather线程也是在第一次接收外部jvm命令时,进行初始化工作。
Finalizer: 用来执行所有用户Finalizer 方法的线程
Reference Handler :它主要用于处理引用对象本身(软引用、弱引用、虚引用)的垃圾回收问题。
public static void main(String[] args) {
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
for (ThreadInfo threadInfo : threadInfos) {
System.out.println("[" + threadInfo.getThreadId() + "]" + " " + threadInfo.getThreadName());
}
}
类Thread
接口Runnable
接口Callable
接口Runnable与接口Callable区别
(1)Callable规定的方法是call(),Runnable规定的方法是run()。其中Runnable可以提交给Thread来包装下,直接启动一个线程来执行,而Callable则一般都是提交给ExecuteService来执行。
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得
(3)Callable方法可以抛出异常,Runnable方法不可以
(4)运行Callable任务可以拿到一个Future对象,表示异步计算的结果。
进入Blocked状态,是在竞争锁的过程中,比如synchronized导致的竞争。从而进入blocked状态。
Waiting/Timed_Waiting是在调用了wait()之后,进入了waiting状态。待notify()/notifyAll()之后,就进入Blocked状态。然后竞争锁,从而可以获取处理机,进行执行操作。
Notify() vs NotifyAll()
notify: 从waiting等待队列中,随机选取一个线程进行唤醒。
notifyAll: 将改对象的waiting等待队列中的所有线程唤醒,并入blocked状态。然后由其自由竞争锁,依次执行,最终直到所有的线程都依次获取锁,并执行完毕。队列中就没有等待的线程。
线程只有6种状态。整个生命周期就是这几种状态的切换。
run()和start() :run方法就是普通对象的普通方法,只有调用了start()后,Java才会将线程对象和操作系统中实际的线程进行映射,再来执行run方法。
run 和 start区别代码StartAndRun.java
yield() :让出cpu的执行权,将线程从运行转到可运行状态,但是下个时间片,该线程依然有可能被再次选中运行。
线程的优先级
取值为1~10,缺省为5,但线程的优先级不可靠,不建议作为线程开发时候的手段
守护线程
和主线程共死,finally不能保证一定执行
DaemonThread.java
线程自然终止:自然执行完或抛出未处理异常
stop(),resume(),suspend()已不建议使用,stop()会导致线程不会正确释放资源,suspend()容易导致死锁。
问题:interrupt是怎样避免suspend之类的死锁的?是使用wait notify实现的?
java线程是协作式,而非抢占式
调用一个线程的interrupt() 方法中断一个线程,并不是强行关闭这个线程,只是跟这个线程打个招呼,将线程的中断标志位置为true,线程是否中断,由线程本身决定。
isInterrupted() 判定当前线程是否处于中断状态。
static方法interrupted() 判定当前线程是否处于中断状态,同时中断标志位改为false。
方法里如果抛出InterruptedException,线程的中断标志位会被复位成false,如果确实是需要中断线程,要求我们自己在catch语句块里再次调用interrupt()。
抛出异常HasInterruptException.java
参考EndRunnable.java
参考EndThread.java
-----------------------------------补充---------------------------------------
当一个方法后面声明可能会抛出InterruptedException 异常时,说明该方法是可能会花一点时间,但是可以取消的方法。
抛InterruptedException的代表方法有:
等待和通知的标准范式
等待方:
1.获取对象的锁
2.循环里判断条件是否满足,不满足调用wait方法
3.条件满足执行业务逻辑
通知方:
1.获取对象锁
2.改变条件
3.通知所有等待在对象的线程
notify和notifyAll应该用谁?
尽量使用notifyAll,使用notify有可能发生信号丢失的情况。
notify和notifyAll实例-快递类Express.java
notify和notifyAll实例-测试类TestWN.java
等待超时模式实现一个连接池
假设等待时长T,当前时间now + T以后超时
等待超时模式——数据库连接池框架
核心类wait-notifyAll DBPool.java
测试类DBPoolTest.java
long overtime = now + T
long remain = T;
while (result 不满足条件 && remain > 0) {
wait(remain);
remain = overtime – now;
}
return result;
转自:https://www.jianshu.com/p/492f45ea7e64
标签:判断 blank 处理 进程 弱引用 操作系统 单位 必须 结束
原文地址:https://www.cnblogs.com/wx170119/p/10451898.html