Java中的线程总结
线程
一、线程的生命周期
1. 进程与线程的定义
(1) 定义:可以简单的理解进程与线程。可以把进程看成一项具体的任务,而线程是为了完成该任务来分解的子任务。
(2) 比如小明今天下5点要去理发店剪头发,这是一项任务(进程),理发店的人可能比较多,因此理发的环节有洗、剪、吹。这每一个环节就是子任务(线程)。
(3) 多线程可以提高效率。
2. 进程与线程的特征
(1)线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位。
(2)一个进程由一个或多个线程组成,线程是一个进程中的代码不同执行路线。
(3)进程之间相互独立,同一进程下的多个线程共享程序的内存空间以及资源。
(4)线程也被认为是轻量级的进程。
3. 线程的生命周期
线程的生命周期一共有5个阶段:创建、就绪、运行、阻塞、自然死亡。
(1)创建有3种方式(二中有解释)
(2)就绪:start();此时并没有执行,就绪不一定CPU(抢占式)会执行
(3)运行:run()和call()
(4)阻塞(block)(4种):
-
sleep()
自己休眠一定时间,释放资源,让其他资源去抢占。当休眠时间过后,变为就绪状态,重新去抢占CPU资源。 -
yield()
自己释放资源后,立马变成就绪状态去抢夺资源。 -
join()
直到调用join方法的线程执行完毕才能访问资源。 -
wait()
只能在synchronized语句中使用。当一个线程执行到wait方法时,它就进入到一个和该对象相关的等待池,同时释放对象的机锁,使得其他线程能够访问,可以通过notify,notifyAll方法来唤醒等待的线程
(5)自然死亡状态(不包括意外死亡)
二、创建线程的3种方式
1.继承Thread类
继承Thread类来创建线程,然后重写Thread类里面的run()方法。
package simeng.thread;
public class ThreadDemo01 {
//此处的main也是一个线程哦,叫做主线程!
public static void main(String[] args) {
Thread t1=new MyThread();
Thread t2=new MyThread();
Thread t3=new MyThread();
t1.start();
t2.start();
t3.start();
}
/**
* 自定义的线程类,完成1到10的打印
* @author Ssimeng
*
*/
public static class MyThread extends Thread{
@Override
public void run() {
for(int i=0;i<10;i++) {
System.out.println(Thread.currentThread().getName()+": "+i);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
结论:线程是抢占式的,处在runnable状态下的线程,谁抢到资源谁就可以执行,因此顺序是无法确定的。
执行结果:
2.实现Runnable接口
2.实现Runnable接口来创建线程,然后重写run()方法。
package simeng.thread;
public class ThreadDemo02 {
public static void main(String[] args) {
Thread t1=new Thread(new MyThread2());
Thread t2=new Thread(new MyThread2());
Thread t3=new Thread(new MyThread2());
t1.start();
t2.start();
t3.start();
}
/**
* 采用实现Runnable接口的方式自定义线程
* 功能依旧是打印1到10,与继承Thread类的效果一样
* @author SSimeng
*
*/
public static class MyThread2 implements Runnable{
@Override
public void run() {
for(int i=0;i<10;i++) {
System.out.println(Thread.currentThread().getName()+": "+i);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
3.实现Callable接口
3.实现Callable接口来创建线程,然后重写call()方法。
package simeng.newthread;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class ThreadDemo03 {
public static void main(String[] args) throws Exception {
//FutureTask实现了Runnable接口
Thread t1=new Thread(new FutureTask<Integer>(new Mythread03())