进程与线程
进程:
a)一个应用程序启动并分配到内存资源,此时就叫做进程。
案列 :迅雷下载是一个应用程序,如果启动运行,此时叫做进程,迅雷可以同时下载多个任务,可以说每一个任务就是一个线程。
一个任务看成一个顺序流执行
b) 线程:
进程中的执行单位:线程
c)线程的并发执行
多线程并发执行:
多个线程看起来同时执行,实质上同一时刻多个线程中只能有一个线程在执行。
多线程并发执行的原理:
任何一个线程要想执行,必须获取到时间片(内存资源),在一个进程中可以有多个线程,多线程并发执行实质上某一时刻只有一个线程的执行。
d) 多线程调度是抢占式的
e) 多进程并发执行原理同多线程相同
f) 并发和并行的区别
i. 并发:看起来同时运行多个,但是某一时刻之后一个在执行。
ii. 并行:看起来同时运行多个,实际上某一时刻真的有多个在执行。
- 一个CPU某一时刻只能执行一个任务,如果现在有多个CPU,多个CPU某一时刻各有任务在同时执行,就叫做并行执行。
线程的生命状态:
新建状态(new)
就绪状态(Runnable)
运行状态(Running)
阻塞状态(Blocked)
死亡状态(Dead)
如下图
2.线程的创建
线程的目的(作用):执行任务
方式一:继承Thread类
创建线程的方式一:继承Thread类:将线程对象和任务绑定了
步骤:
1. 自定义一个类继承Thread类
2. 重写父类中的run()
3. 创建当前类的对象
4. 调用start方法启动
Thread类实现了Runnable接口
案例:创建两个线程,分别循环10次输出内容
线程类
/**
* 线程类
* @author adminitartor
*
*/
public class ThreadDemo extends Thread {
//方法体中的代码实现任务
@Override
public void run() {
//输出1-20之间的所有数字
for(int i=1;i<=30;i++){
System.out.println(Thread.currentThread().getName()+"-"+i);
}
}
}
测试类
public class ThreadTest {
public static void main(String[] args) {
/*
* 创建一个线程对象,用于执行输出
* 1-20之间所有的数字任务
*/
//创建线程
// ThreadDemo thread = new ThreadDemo();
//启动线程让其进入就绪状态
// thread.run(); 只是完成了一次普通方法的调用,并不是启动线程。
//启动
// thread.start();
/*
* 启动多个线程,看线程调度是否是抢占式的
*/
ThreadDemo thread1 = new ThreadDemo();
ThreadDemo thread2 = new ThreadDemo();
thread1.start();
thread2.start();
// thread1.run();
// thread2.run();
}
}
方式二:实现Runnable接口:可以实现线程和任务的分离
创建线程的方式二:实现Runnable接口:自定义的类是一个任务类
步骤:
1. 自定义一个类实现Runnable接口
2. 重写run()
3. 创建此类的对象 - obj
4. 创建Thread类对象,将obj作为参数传递进来
5. 调用start方法启动线程
任务类
public class RunnableDemo implements Runnable {
@Override
public void run() {
for(int i=1;i<=20;i++){
System.out.println(Thread.currentThread().getName()+"-"+i);
}
}
}
测试类
public class RunnableTest {
public static void main(String[] args) {
/*
* 创建线程对象并启动
*/
// RunnableDemo demo = new RunnableDemo();
// Thread thread = new Thread(demo);
// thread.start();
/*
* 多线程并发执行
* 线程调度:抢占式的
*/
RunnableDemo task = new RunnableDemo();
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
}
}
使用匿名内部类创建线程
public class NoNameInnerClassThread {
public static void main(String[] args) {
//执行两个任务,并发执行
//创建两个线程对象并启动 - 匿名内部类
Thread thread1 = new Thread(){
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+"执行任务1");
}
}
};
Runnable task = new Runnable() {
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+"执行任务2");
}
}
};
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
}
}
3.线程的方法
静态方法
thread.currentThread() -Thread
获得当前正在执行的线程对象
Thread.sleep()
该方法会使当前线程进入阻塞状态指定毫秒,当阻塞指定毫秒后,当前线程会重新进入就绪状态,等待分配时间片。
Thread.yield()
让步,正执行的线程,让出时间片,让其他线程有机会执行
其他方法
String getName():返回该线程的名称
给线程重命名方式:
setName(String) - void
Thread(String name)
interrupt():唤醒线程
线程调用此方法,如果当前线程是运行状态,此方法无效
如果当前线程是阻塞状态,此方法才有效
join():
该方法可以协调多个线程之间同步运行.
异步:各自执行各自的,互不影响
同步与异步:
所谓同步执行指的执行有先后顺序.异步执行则执行没有顺序,各干各的.
多线程运行本身的设计是异步运行的.但在某些业务逻辑中需要他们执行各自任务时要有先后,这时就需要协调这些线程之间同步运行.
在线程A中让线程Bjoin,那么线程A进入阻塞状态,线程B执行,直到B执行完,线程A的阻塞才会解除。
多线程图谱