多线程笔记1——基础

1.基础

1.1 并发与并行

并发:concurrent 同一时间应对多件事的能力    eg.一个人交替做多件事

并行:parallel 同一时间动手做多件事的能力    eg.三个人每人负责一件事

1.2 同步与异步

以方法调用为例:需要等待结果返回才能继续运行的是同步;不需要的是异步。

1.3 创建线程

三种:继承Thead;实现Runnable接口;FutureTask

1.4 查看线程和进程方法

windows:任务管理器/ cmd中tasklist查看进程;taskkill杀死进程

linux:

查看所有进程信息:ps -fe
查看指定进程信息:ps -fe | grep  xxxxx
查看java进程:jps
杀死进程: kill 进程id
查看动态进程信息:top

查看某进程中线程信息:top -H -p 进程id
查看java中某一刻线程信息:jstack 进程id

2.常见方法

2.1 Thread的方法

名称 介绍
start()和run() run()仅仅是调用方法,start()开启并运行新线程
sleep()

让线程从Running进入Time Waiting状态;

其他线程可以通过interrupt()方法打断在睡眠的线程,这时sleep方法会抛出InterruptedException;

睡眠结束了进入阻塞队列;

建议使用juc包下的TimeUnit类的sleep方法代替Thread下的sleep方法,可读性更好。

yield() 让当前线程从Running进入阻塞队列,重新分配(但有可能重新调度回自己)
setStatus() 设计优先级1-10,默认5。然还还是主要根据操作系统分配
join()和join(long n) 等待调用join的线程运行结束/限制最大等待时间,该线程会先进入阻塞状态,底层原理与wait()相同。eg.在主线程中t1.join(),会等待t1运行结束再执行下面代码
interrupt()

对于进入sleep的线程,打断sleep的线程,让其重新回到阻塞队列

对于正常的线程,该线程可以配合isInterrupted()方法判断自己是否被打断

stop()/ suspend()/ resume() 停止线程运行/ 挂起线程/ 恢复线程运行; 都不推荐使用,如果该线程在执行同步代码块被停止,对象锁无法释放,引起线程同步问题。三种方法都已过时

守护线程setDaemon():在该例子中,当主线程运行完,守护线程t1也会强制结束

注:垃圾回收线程就是一种守护线程

多线程笔记1——基础_第1张图片

2.2 锁对象的方法:wait和notify

当某一对象获得锁并执行时,如果想退出,执行wait方法,该线程会进入WaitSet并变为WAITING状态

WAITING与BLOCKED状态的区别在于:BLOCKED线程会在Owner释放锁之后唤醒参与竞争;WAITING线程会在Owner线程调用notify或者notifyAll时唤醒,进入EntryList重新竞争

wait和sleep的区别:(1)sleep是thread的方法,wait是Object的方法;(2)sleep不需和synchronized配合使用,wait需要和synchronized一起使用;(3)sleep睡眠时不会释放锁,wait会释放锁

obj.notify()和obj.notifyAll()区别:前者随机唤醒WaitSet中任意一个线程,后者全部唤醒 

常用模板

多线程笔记1——基础_第2张图片

2.3 LockSupport类中的方法:park()和unpark(thread)  

多线程笔记1——基础_第3张图片

底层原理:

调用park时:如果counter = 1,设置counter = 0,则继续运行;如果counter = 0,则获得mutex互斥锁,停止线程,让线程进入_cond,再次设置counter = 0。

调用unpark时:先设置counter = 1,唤醒线程(如果线程在_cond中)

多线程笔记1——基础_第4张图片

3.线程状态

(1)从操作系统层面:有五种

多线程笔记1——基础_第5张图片

(2)从java API层面:根据Thread.State枚举,分为六种(NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED)

多线程笔记1——基础_第6张图片

1 thread1.start()
2

thread1线程获得了锁对象之后

调用object.wait() :thread1从RUNNABLE变成WAITING

调用object.notify(),object.notifyAll(),thread2.interrupt():

       锁竞争成功:thread1线程从 WAITING变成RUNNABLE

       锁竞争失败:thread1线程从 WAITING变成BLOCKED

3 thread2.join():thread1从RUNNABLE变成WAITING,直到thread2结束,thread1再变回RUNNABLE
4

LockSupport.park():让当前线程从RUNNABLE变成WAITING

LockSupport.unpart(目标线程):让目标线程从WAITING变回RUNNABLE

5

thread1线程获得了锁对象之后:调用object.wait(时间) 

6 thread2.join(时间)
7 thread1.sleep(时间)
8 LockSupport.parkNanos(时间)  或者  LockSupport.parkUntil(时间)
9

thread1线程获取锁对象失败会进入BLOCKED。

如果锁被释放,会通知该对象上所有BLOCKED的线程重新竞争

10 代码执行完毕

 

你可能感兴趣的:(JAVA多线程)