一、进程与线程
1.进程的概念
- 线程隶属于某个进程,进程是一个程序的执行周期,但是我们的线程是执行进程中的某个任务
- 所以如果进程不存在的话,那么线程自然也就不会存在了。
- 我们应该时刻将线程和任务对等起来,运行一个程序启动一个进程。这样就可以提升沃恩程序的运行能力。
2.进程与线程的区别
(1)对于这个问题,我们首先需要知道进程与线程的概念,从它们的概念上我们可以知道进程是宏观的,它相对于线程来说是它的载体,它是执行一个任务时的周期。但是对于我们的线程,它时隶属于进程了,它的存在必须以一个进程为载体,所以线程只是进程里面的一部分。
(2)进程的创建在电脑里面同一时间里一直创建是有限的,但是线程只要进程不终止它就可以一直创建。
3.线程状态(这个图非常重要,记住,这个JavaSE阶段唯一一个要自己会画的图)
对上面图的解释:
创建:创建线程,创建好一个线程是处于就绪状态。它处于就绪状态等待执行,不是有谁去通知它,而是它此时没有获取CPU的时间片段。
CPU的时间片段:对于单核的CPU在同一时间只能处理一个线程。它即将自己的时间片段做了很多分割,就绪是因为CPU处于忙的状态。
阻塞状态:出现阻塞状态时因为当一个线程在执行了很长时间以后CPU会将它暂停一会,将时间片段给另外的线程使用,这个时候这个线程就处于阻塞状态;当阻塞一会以后CPU又重新分配时间片段给这个线程的时候,它就会从阻塞状态到就绪状态,然后再到运行状态,接着上一次的zh中断地方开始执行。
终止:就是线程执行完毕以后的状态。
对于线程的状态:
(1)创建----就绪
(2)创建-----就绪----运行----终止
(3)创建----就绪----阻塞
(4)创建----就绪----运行----阻塞-----就绪----运行----终止
二、多线程的实现
1.通过继承Thread类实现多线程
利用这个继承的类来实现创建进程,它的构造方法我们可以自己定义,根据我们的需求。
package com.wschase.xianchengjianjie;
/**1.进程与线程
* (1)通过继承Thread类实现多线程 :用继承Thread的这个类来创建线程对象,我们可以根据自己的需要覆写这个子类的构造方法
* (2)Thread的run方法不会启动线程,只是普通的方法调用
* (3)Thread的start方法启动线程 ,start方法只需要调用一次
* Author:WSChase
* Created:2019/1/8
*/
public class Thread1 extends Thread{
public final String title;
public Thread1(String title) {
this.title = title;
}
@Override
public void run() {
//多线程处理的业务逻辑
for (int i=0;i<10;i++){
System.out.println(this.title+" "+i);
}
}
public static void main(String[] args) {
//注意:下面的执行是按照顺序执行的,run方法只是一个普通方法,它不能启动线程
//注意:先启动的不一定先执行,它们都在就绪状态。
Thread1 thread1=new Thread1("线程1");
//thread1.run();
thread1.start();
Thread1 thread11=new Thread1("线程2");
//thread11.run();
thread11.start();
}
}
2.通过实现Runnable接口创建多线程
(1)代理模式
采用这个方法,我们需要用到开闭原则,用一个代理来实现Runnable接口,里面是真正要实现的功能,而我们在另外一个类里面只是使用这个类里面的方法即可。
package com.wschase.xianchengjianjie;
/**2.Runnable接口实现多线程----通过代理模式来实现的,这样保证了开闭原则
* 使用多线程方法
* 1.复用业务逻辑
* 2.实现runnable接口,可以继续实现接口
* Author:WSChase
* Created:2019/1/8
*/
public class PrintInfo {
//这是一个普通任务
public void print(Object ... args){
for(int i=0;i<args.length;i++){
System.out.println(args[i]);
}
}
public static void main(String[] args) {
// new PrintInfo().print("hello","world");
//使用多线程访问----通过Runnable
PrintInfo task=new PrintInfo();
Runnable runnable=new PersonInfo(task);
//public Thread(Runnable target)----》这是Thread的构造方法
Thread thread=new Thread(runnable);//Thread方法里面需要RUnnable接口的实例化对象
thread.start();
}
}
//这是个普通的类实现Runnable接口,这个类就是代理类,代理模式
class PersonInfo implements Runnable{
private final PrintInfo task;
public PersonInfo(PrintInfo task) {
this.task = task;
}
@Override
public void run() {
this.task.print("hello","java","best");
}
}
(2)Lambda表达式
将代理类里面实现的方法直接在我们的覆写方法中实现。
package com.wschase.xianchengjianjie;
/**2.Runnable接口实现多线程
(1)通过代理模式来实现的,这样保证了开闭原则
* 使用多线程方法
* 1.复用业务逻辑
* 2.实现runnable接口,可以继续实现接口
* (2)可以采用匿名内部类----》再转化为Lambda表达式
* Author:WSChase
* Created:2019/1/8
*/
public class PrintInfo {
//这是一个普通任务
public void print(Object ... args){
for(int i=0;i<args.length;i++){
System.out.println(args[i]);
}
}
public static void main(String[] args) {
// new PrintInfo().print("hello","world");
//使用多线程访问----通过Runnable
PrintInfo task=new PrintInfo();
// Runnable runnable=new PersonInfo(task);
// //public Thread(Runnable target)----》这是Thread的构造方法
// Thread thread=new Thread(runnable);//Thread方法里面需要RUnnable接口的实例化对象
// thread.start();
//(2)采用lambda表达式
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
//直接实现了我们代理类里面的功能,不需要再创建一个类了
task.print("hello","nihao");
}
});
thread.start();
}
}