多线程的深入(一,线程的一些基础知识简单回顾)
一、线程的创建
package com.key.demo.queue.thread; public class CreateThread { public static void main(String[] args) { TestThread1 thread1 = new TestThread1(); thread1.start(); // thread1.run(); Thread thread2 = new Thread(new TestThread2()); thread2.start(); // thread2.run(); } } class TestThread1 extends Thread { public void run() { System.out.println("start ~ currentThread().getName():" + currentThread().getName()); } } class TestThread2 implements Runnable { public void run() { System.out.println("start ~ currentThread().getName():" + Thread.currentThread().getName()); } }
二、线程的转换状态
1.新建状态 New。
2.就绪状态 Rannable 调用了start(),位于可运行池中,等待获得CPU的使用权。
3.运行状态 Running 占用CPU,运行逻辑代码。
4.阻塞状态 Blocked 因为某些原因放弃CPU,暂时停止运行。
当线程处于阻塞状态,JVM不会分配CPU给该线程,直到线程重新进入就绪状态,才有机会进入运行状态。
阻塞状态分三种:
位于对象等待池中的阻塞状态(线程通信):正在运行的线程执行了对象的wait(),JVM会把该线程放入对象等待池中。
位于对象锁池中的阻塞状态(线程同步):当对象处于运行状态,视图获得某个对象的同步锁时,如果该对象被其他线程占用,JVM会把该线程放入对象锁池中。
其他阻塞状态:线程的sleep()、调用其他线程的join()、发出I/O请求。
4.死亡状态 Dead 退出run(),结束生命周期。
三、线程调度
1.希望一个线程明确地让另外一个线程占用CPU,有如下方式可行:
当前线程sleep()
当前线程yield()--不推荐使用,测试调bug推荐使用;
调用另一个线程的join()。
2.通过调整可运行池中线程的优先级一定程度上可以调度。(JVM线程优先级有十级,基于各种操作系统优先级的缘故,推荐用这三个级别)
thread.setPriority(Thread.MAX_PRIORITY);--10 thread.setPriority(Thread.MIN_PRIORITY);--1 thread.setPriority(Thread.NORM_PRIORITY);--5
四、后台线程
所有前台线程结束后,后台线程才结束生命周期。
设置一个线程为后台线程时,setDeamon(true)在线程start()之前。
前台线程默认创建的都是前台线程,后台同理。
五、定时器Timer
new Timer(定时任务,延迟时间(毫秒),间隔时间(毫秒));