一,线程的介绍
进程:正在运行的程序,负责了这个程序的内存空间分配,代表了内存中的执行区域。
线程:就是在一个进程中负责一个执行路径。
多线程:就是在一个进程中多个执行路径同时执行。
进程在Windows的操作系统中,可以看成为一个程序。那么线程就是进程中代码执行的路径,多线程就是进程中多个代码的执行路径。
多线程的好处:
1. 解决了一个进程里面可以同时运行多个任务(执行路径)。
2. 提供资源的利用率,而不是提供效率。
多线程的弊端:
1. 降低了一个进程里面的线程的执行频率。
2. 对线程进行管理要求额外的 CPU开销。线程的使用会给系统带来上下文切换的额外负担。
3. 公有变量的同时读或写。当多个线程需要对公有变量进行写操作时,后一个线程往往会修改掉前一个线程存放的数据,发生线程安全问题。
4. 线程的死锁。即较长时间的等待或资源竞争以及死锁等多线程症状。
二,创建线程的方式
方式一:1,继承Thread
2,复写run方法,把执行的代码写在run方法内
3,调用start方法
class TestTread extends Thread{
@Override
public void run() {
for(int i=0; i<10; i++){
System.out.println("线程一.....");
}
}
}
public class CreateTreadOne {
public static void main(String[] args) {
TestTread thread = new TestTread();
thread.start();
for(int i=0; i<10; i++){
System.out.println("主线程.....");
}
}
}
执行图:
方式二:
1,实现Runable接口
2,重写Runable接口的run方法,把执行代码写在run方法内
3,通过Thread类创建线程,并把实现Runable接口的类 作为参数传递给Thread类
4,调用Thread类的start方法开启线程(内部就是调用的Runable的run方法)
class TestTread2 implements Runnable{
public void run() {
for(int i=0; i<10; i++){
System.out.println("自定义线程一.....");
}
}
}
public class CreateTreadTwo {
public static void main(String[] args) {
TestTread2 runalbe = new TestTread2();
Thread thread = new Thread(runalbe);//把runable的实现类传给Thread
thread.start();
for(int i=0; i<10; i++){
System.out.println("主线程.....");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
运行图:
线程使用的细节:
1,如果直接调用run方法,而不是start方法,则不会启动多线程,会看成普通的方法运行。
2,线程的启动只能一次,否则就会抛出异常
3,匿名内部类的线程实现方式
三,线程的状态
生命周期:
1,创建Tread对象
2,调用start方法后进入可运行状态,此时不具有CPU运行资格,具有等待CPU资格
3,得到Cpu的执行权后,进入运行状态, 此时具有CPU运行资格,也具等待CPU资格。如果被抢夺了CPU的执行权则进入了可运行状态,如果调用了sleep wait等方法,则进入了堵塞状态。进入堵塞状态后。被唤醒后就会进入可运行状态。
4,结束,销毁线程
注意:运行状态下线程如果是由sleep进入了堵塞状态,那么如果超过了指定的睡眠时间,则自动进入可运行状态。如果是由wait进入了堵塞状态,则必须等待其他线程唤醒后才能进入可运行状态。