1.2.进程和线程的区别?
进程就是一个完整的应用程序,如qq软件,浏览器软件等。一个进程中至少会有一个线程,线程是进程的基本组成单位。我们可以将阿里巴巴看作一个进程,然后将阿里下面的支付宝,淘宝,天猫等看作一个线程,阿里这个进程是由许多的像支付宝这样的线程组成的,支付宝线程,淘宝线程,天猫线程都在同时运行,程序中多个线程就是这样,多个功能可以同时执行,就像你在用网易云的时候你可以一边听歌一边查询自己想听的歌。在线程中资源是共享的,而在进程中是不可以共享资源的。在阿里这个进程中的支付宝线程,淘汰线程,天猫线程,在这些线程中是可以进行员工调动的,也可以相互交流和开会商量如何把拼多多干掉的,这就是资源贡献。但是阿里就不可能与拼多多,京东直接进行人员调动。这就是资源不共享。其实每一个线程都有一个栈,用来执行自己线程中的方法,所以线程的执行是互不干扰的。进程会向电脑的cpu申请资源,而线程是申请进程的资源。线程要抢夺cpu的时间片才可以运行,谁抢到谁运行,所以线程的执行是随机的。就像在阿里大楼里上班的员工下班一样,大楼中一共就有那么多电梯,这个电梯就是cup时间片,下班的时候谁抢先进入电梯,谁就可以快点下楼。这个抢到电梯的可能是支付宝的员工也可以是淘宝的员工还有可以是天猫的员工,这就像线程执行的随机性。当时线程抢到cup时间片,最多用20毫秒然后重新再抢。
2.并发和并行
并发:多个线程同时发生,交替执行。
并行:多个线程同时执行。
3.线程的优缺点
优点:提高cpu资源的利用率,可以是程序同时执行多个功能,
缺点:加重cpu的负担,降低软件的执行速度,
4.线程的两种创建方式
线程有两种常用的创建方式第一种是继承Thread类,第二种是实现Runnable接口
第一种方式(实际开发中不常用):首先下一个自定义一个线程类继承Thread重写run()方法,然后在main函数中new这个线程类对象,对象调用start()方法,启动线程,启动线程之后就会自动执行线程类中的run()方法
public class TestThread01 {
public static void main(String[] args){
FistThreadTest fistThreadTest = new FistThreadTest();
fistThreadTest.start();
for (int i = 0;i < 10;i ++){
System.out.println("main方法中线程:" + i);
}
}
}
//1.创建线程类继承(extends)Thread接口,重写run()方法
//2.在main方法中new线程类对象,调用start()方法,启动线程,启动线程后会自动执行run()方法
class FistThreadTest extends Thread{
//执行的线程方放就是执行的这个run方法
@Override
public void run() {
for (int i = 0; i < 10;i ++){
System.out.println("自己创建线程:" + i);
}
}
}
运行结果
第二种方式(开发中常用):首先自定义一个线程类实现Runnable接口然后重写run方法,然后在main方法中new出来Thread对象参数是自定义类对象,然后Thread对象调用start方法
public class TestThread02 {
public static void main(String[] args){
Thread threas = new Thread(new SecondThreadTest(), "自定义线程类SecondThreadTest");
//参数 第一个参数是自定义实现Runnable接口的类对象,第二个参数是这个线程的名字
threas.start();
for (int i = 100;i < 110;i ++){
System.out.println("main方法线程:" + i);
}
}
}
//1.自定义线程类实现Runnable接口,重写run()方法
//2.然后在main方法中new出来Thread对象参数是自定义线程类对象,thread对象调用start方法
class SecondThreadTest implements Runnable{
@Override
public void run() {
for (int i = 0;i < 10;i ++){
System.out.println("自定义线程类SecondThreadTest:" + i);
}
}
}
运行结果