理解线程
其实搞清楚线程和进程的关系就很好理解线程了。比如说你开一个微信,那微信就是一个进程, 但是微信里你同时和不同的人聊天,那不同的窗口就是一个个线程。线程实际就是可执行程序的最小单元, 是一个进程的不同执行路径。
线程的两种创建方式
线程的创建有很多种写法,但是归根结底就只有两种,一种是实现runnable接口,一种是继承Thread类
public class HowToCreateThread{
static class MyThread extends Thread{
@override
public void run(){
System.out.println("hello Thread!");
}
static class MyRun implements Runnable{
@override
public void run(){
System.out.println("hello run!");
}
}
public static void main(String[] args){
new MyThread().start();
new Thread(new MyRun()).start();
//其实就是第二种方式的lambda表达式
new Thread(()->{
System.out.println("hello run!");
})
}
}
}
熟悉调用线程的几个函数
- sleep()
- 调用Thread.sleep(), 该线程就进入睡眠中,让别的线程去使用CPU。等时间到了,它再进入等待序列。
- yield()
- 调用Thread.yield(),就是谦让的退出一下,进入等待的队列,让其他线程有机会可以使用CPU。
- join()
- 有两个线程,一个是t1, 一个是t2, 在t1里面调用t2.join(),则t1会等待t2执行完再执行t1.
public class Sleep_Yield_Join(){
static void testSleep(){
new Thread(()->{
for(int i = 0; i< 100; i++)
System.out.println(i);
try{
Thread.sleep(500);
}catch(InterruptException e){
e.printStackTrace();
}
}).start();
};
static void testYield(){
new Thread(()->{
for(int i = 0; i< 100; i++)
System.out.println(i);
try{
Thread.yeild();
}catch(InterruptException e){
e.printStackTrace();
}
}).start();
};
static void testJoin(){
Thread t1 = new Thread(()->{
for(int i = 0; i< 100; i++)
System.out.println(i);
try{
Thread.sleep(500);
}catch(InterruptException e){
e.printStackTrace();
}
}).start();
Thread t2 = new Thread(()->{
try{
t1.join();
}catch(InterruptException e){
e.printStackTrace();
}
}).start();
};
static void main(String[] args){
testSleep();
testYield();
testJoin();
}
}
线程的状态
- 开始:start()
- 就绪/Running:线程开始后,TimedWaiting结束,notify(),notifyAll(),LockSupport.unpark();
- 停止:线程结束后
- TimedWaiting:被调用sleep(time),wait(time),LockSupport.park(time)
- Waiting: 被调用wait(),join(),LockSupport.park()
- Blocked: 在同步代码块里