第一节:线程的基本概念
1、什么是进程?
- 一个正在运行的程序,比如qq,微信
2、什么是线程?
- 一个进程中的最小执行单位,一个进程中不同的执行路径
3、创建线程的三种方式
-
Thread类(继承 extends)
-
public class MyThread extends Thread { @Override public void run() { // 执行逻辑 } }
-
-
Runable接口(实现 implement)
-
public class MyRunnable implements Runnable{ @Override public void run() { // 执行逻辑 } }
-
-
Callable接口(实现 implement)
-
public class MyCallable implements Callable<String> { @Override public String call() throws Exception { // 执行逻辑 return "true"; } }
-
4、启动线程的五种方式
public class MyTest {
public static void main(String[] args) {
//启动线程五种方式:
// 1.Thread 启动线程
new MyThread().start();
// 2.Runnable 启动线程:两种方式
new Thread(new MyRunnable()).start();
// 3.Runnable
new Thread(() -> {
// 执行逻辑
}).start();
// 4.Callable 启动线程
new Thread(new FutureTask<String>(new MyCallable())).start();
// 5.线程池 启动线程
ExecutorService service = Executors.newCachedThreadPool();
service.execute(()->{
// 执行逻辑
});
}
}
5、线程的基础方法
-
sleep:睡眠,使当前线程睡一段时间再继续执行
- 复活方式:通过形参传入睡眠时间,对线程进行指定时间睡眠,时间结束,线程复活
-
Yield:让步,让出执行权,回到等待队列中,等下一次cpu调度到当前线程再继续执行
- 注意:此处回到等待队列,仍可以抢执行权哦!
-
join:加入,同步执行,T2线程操作T1线程让出执行权,直到T2线程全部执行完毕,T1线程才能进行抢执行权
- 其实类似同步调用,T2线程中调用T1线程的方法,让T1先执行其逻辑,执行完我在继续执行下面的逻辑
public class Test_sleep_yield_join { public static void main(String[] args) { // testSleep(); // testYiled(); testJoin(); } /** * sleep:睡眠,使当前线程睡一段时间再继续执行 * 1. 复活方式:通过形参传入睡眠时间,对线程进行指定时间睡眠,时间结束,线程复活! */ static void testSleep(){ new Thread(()->{ for (int i = 0; i < 100; i++) { System.out.println("A"+i); if (i == 50){ try { Thread.sleep(2000); } catch (InterruptedException e) { throw new RuntimeException(e); } } } }).start(); } /** * Yield:让步,让出执行权,回到等待队列中,等下一次cpu调度到当前线程再继续执行 * 1. 注意:此处回到等待队列,仍可以抢执行权哦! */ static void testYiled(){ new Thread(()->{ for (int i = 0; i < 100; i++) { System.out.println("A"+i); if (i%10 == 0) Thread.yield(); } }).start(); new Thread(()->{ for (int i = 0; i < 100; i++) { System.out.println("B"+i); if (i%10 == 0) Thread.yield(); } }).start(); } /** * join:加入,同步执行,T2线程操作T1线程让出执行权,直到T2线程全部执行完毕,T1线程才能进行抢执行权 * 1. 其实类似同步调用,T2线程中调用T1线程的方法,让T1先执行其逻辑,执行完我在继续执行下面的逻辑 */ static void testJoin(){ Thread t1 = new Thread(()->{ for (int i = 0; i < 20; i++) { System.out.println("A"+i); try { Thread.sleep(500); } catch (InterruptedException e) { throw new RuntimeException(e); } } }); Thread t2 = new Thread(()->{ try { t1.join(); } catch (InterruptedException e) { throw new RuntimeException(e); } for (int i = 0; i < 20; i++) { System.out.println("B"+i); } }); t1.start(); t2.start(); } }
6、线程状态
- 以下状态由JVM管理,通过操作系统进行改变!
-
线程基本状态
- 新建状态 new
- 就绪状态 ready
- 运行状态 running
- 结束状态 terminated
-
Runnable的其他状态变迁
- 就绪和运行状态是Runnable的内部状态
-
TimedWaiting 等待
- 按照时间等待,等时间结束自己就会回去了
- Thread.sleep(time)
- o.wait(time)
- t.jion(time)
- LockSupport.parkNanos()
- LockSupport.parkUntil()
-
waiting 等待
- 调用进入waiting 等待
- o.wait()
- t.jion()
- LockSupport.park()
- 调用退出waiting 等待,进入Running运行
- o .notify()
- o.notifyAll()
- LockSupport.unpark()
- 调用进入waiting 等待
-
blocked 阻塞
- 比如同步代码块中没有得到锁🔒,就会被阻塞
-
问题一:
- 线程什么状态时会被挂起?挂起是否也算一种状态?
- 回答:???????????
- 线程什么状态时会被挂起?挂起是否也算一种状态?