线程创建
注:以下代码使用while(true) 死循环非必要写法 ,只是为了方便观察 线程的运行
sleep是休眠函数 单位为 ms ,在运行后 会阻塞单位毫秒后继续运行 加上也是方便观察
对于存在 阻塞的代码 都需要抛出异常 受查异常
方法1
创建一个子类 继承Thread 重写 run 方法
注意:
Thread t = new MyThread() 实例化后,并没有真正创建线程,要在 t.start() 后才是真正创建线程。即:在操作系统内核中,创建出对应的 PCB ,然后将 PCB 加入到 系统链表中进行调度。
方法2
创建一个子类 实现 Runnable 接口 重写 run 方法
比较:
方法1 和 方法2 之间的区别在于,方法1 将线程和任务绑定;而方法2 将线程和任务分开,使代码达到高内聚,低耦合的效果 ,任务和线程本身的关系降低。
方法3
使用匿名内部类 ,这个匿名内部类是 Thread 的子类,同时 前面 new 关键字 ,就给这个匿名内部类 创建了一个实例,这一套操作实现了 1.继承 2.方法重写 3.实例化
方法4
使用匿名内部类 实现 Runnable 接口
方法5
lambda 表达式 推荐写法
线程中断
方法1
自己创建标志位 来决定线程是否要结束
创建方法 : 设置一个成员变量
方法2
使用 Thread 自带的标志位函数 isInterrupted() 《—重点掌握 (对于Thread.Interrupted()不做阐释)
(若为 true 时 表示 线程要中断 )
配合 intertupt() 使用
当 interrupt() 遇到 t 线程 没有处于阻塞状态时,interrupt 就会修改内置的标志位 。
当 interrupt() 遇到 t 线程 正在处于阻塞状态时,interrupt 就让线程内部产生阻塞的方法,例如:sleep抛出异常 等
总结为:
线程等待
线程等待 使用 join() 函数,线程之间的执行顺序是完全随机的,看系统的调度,join 就是一种确定线程执行顺序的辅助手段,我们不能控制线程的开始执行顺序,但是我们可以通过 join() 来控制两个线程的结束顺序。
注:对于join() 来说 ,与 sleep() 一样也是会发生阻塞。所以也需要抛出异常。
参数的不同
public void join() 等待线程结束 (死等)
public void join(long millis) 等待线程结束 最多等待 millis 毫秒
public void join(long millis,int nanos) 等待线程结束 最多等待 millis 毫秒 nanos 纳秒 更精确
注:对于死等来说有风险,容易让服务器卡死,无法继续工作,更多的做法是要等待的时候,预期好最多等多久,如果时间到了还没有等来,就要做出一些措施 ~
代码实现 main 线程等待t2 线程 t2 线程等待t1线程
线程休眠
如上述的使用 总结如下:
sleep(long millis) 休眠当前线程 millis 毫秒
sleep(long millis, int nanos) 可以更高的精度休眠
获取线程实例
即: Thread currentThread() 表示返回当前线程对象的引用
我们可以将他 理解为 this,上述代码中的Thread 自带标志位中断while 循环条件中也有用到。