线程的基本概念
之前的硬件,只有一个CPU
之前的OS,只运行一个进程
随着多核CPU的出现,人们开始追求对CPU效率的极致压榨
多线程的程序随之诞生,但随之诞生的,也是非常难以应对的各种并发bug
进程 线程
1. 什么是进程:资源分配的基本单位(静态概念)
2. 什么是线程:资源调度的基本单位(动态概念)
通俗说:一个程序中不同的执行路径
**示例:什么叫做线程**
import java.util.concurrent.TimeUnit;
public class T01_WhatIsThread {
private static class T1 extends Thread {
@Override
public void run() {
for(int i=0; i<10; i++) {
try {
TimeUnit.MICROSECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("T1");
}
}
}
public static void main(String[] args) {
//new T1().run();
new T1().start();
for(int i=0; i<10; i++) {
try {
TimeUnit.MICROSECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("main");
}
}
}
观察上面程序的数据结果,你会看到字符串“T1”和“Main”的交替输出,这就是程序中有两条不同的执行路径在交叉执行,这就是直观概念上的线程,概念性的东西,理解就好,没有必要咬文嚼字的去背文字的定义。
为什么要写多线程程序
为了压榨CPU,提高资源利用率
#启动线程的5种方法
1. new MyThread().start()
2. new Thread(r).start()
3. new Thread(lamda).start()
4. ThreadPool
5. Future Callable and FutureTask
**认识几个线程的方法**
sleep() yield() join()
public class T03_Sleep_Yield_Join {
public static void main(String[] args) {
//testSleep();
//testYield();
testJoin();
}
/*Sleep,意思就是睡眠,当前线程暂停一段时间让给别的线程去运行。Sleep是怎么复活的?由你的睡眠时间而定,等睡眠到规定的时间自动复活*/
static void testSleep() {
new Thread(()->{
for(int i=0; i<100; i++) {
System.out.println("A" + i);
try {
Thread.sleep(500);
//TimeUnit.Milliseconds.sleep(500)
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
/*Yield,就是当前线程正在执行的时候停止下来进入等待队列(就绪状态,CPU依然有可能把这个线程拿出来运行),回到等待队列里在系统的调度算法里头呢还是依然有可能把你刚回去的这个线程拿回来继续执行,当然,更大的可能性是把原来等待的那些拿出一个来执行,所以yield的意思是我让出一下CPU,后面你们能不能抢到那我不管*/
static void testYield() {
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, 意思就是在自己当前线程加入你调用Join的线程(),本线程等待。等调用的线程运行完了,自己再去执行。t1和t2两个线程,在t1的某个点上调用了t2.join,它会跑到t2去运行,t1等待t2运行完毕继续t1运行(自己join自己没有意义) */
static void testJoin() {
Thread t1 = new Thread(()->{
for(int i=0; i<100; i++) {
System.out.println("A" + i);
try {
Thread.sleep(500);
//TimeUnit.Milliseconds.sleep(500)
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(()->{
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i=0; i<100; i++) {
System.out.println("A" + i);
try {
Thread.sleep(500);
//TimeUnit.Milliseconds.sleep(500)
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
}
}