java027多线程的概念及线程的三种创建方式

一,引出多线程:
概念:就是同一时刻多个任务可以同时执行,这就是多线程
比如双十一秒杀产品的时候,是多个人同时抢,而不是先由一个人抢,后面的所有人都等着,这是单线程就很弊端,故而要用到多线程
1,分析:此时如果只有一个while死循环,就会一直输出a,但是有两个死循环,由于第一个while循环始终都循环不出来,所以永远都轮不到1输出,因而下面会报错
在这里插入图片描述
2,把两个程序放入到两个线程下,然后写到匿名内部内的run方法里面,然后分别调用。此时程序不会报错,并且会一直输出a,原因是上面的死循环还没有结束,轮不到下面的循环输出,所以它依然是一个单线程程序
在这里插入图片描述
3,使用

t1.start();
t2.start();

启动多线程,然后系统(java虚拟机)会调用run方法,进行多线程输出
在这里插入图片描述
然后看输出结果,发现a和1在抢线程,谁抢到谁就输出,这就是个多线程输出,可以看出,只要是在多线程底下,就可以实现多个任务同时执行
在这里插入图片描述
二,进程的相关概念:
进程:正在运行中的程序,就比如电脑任务管理器中的QQ浏览器,eclipse,画图,WPS等等,都在电脑后台运行着,这就是进程
在这里插入图片描述
线程:是比进程更小的执行单位,一个进程包含多个线程,比如正在运行的迅雷是一个进程,迅雷里面的多个下载任务是多个线程
再比如任务管理器中的性能
在这里插入图片描述
时间片轮:我们看到的结果是在多线程底下多个任务可以同时执行,其实不然,而是cpu在快速切换去执行每一个线程,由于cpu切换的速度太快以至于我们感觉是同时执行的,其实在同一时刻还是只有一个线程在执行
就像是我们之前做过的数码管实验,10个数码管对应0到9,一秒亮一个数字,就像是单线程执行,但是如果频率过大,超出我们人眼识别的范围,就会觉得是10个数码管同时亮,感觉就像是多线程执行,其实不然
并发:在同一时刻,有多个线程同时执行,其实还是一个cpu在快速切换
并行:在同一个时刻,有多个cpu在同时执行多个线程,这才是真正意义上的同时执行
三,线程的三种创建方式:
1,继承Thread类(不常用,因为继承了Thread类后,由于继承的单继承,不能继承其他类)
main也是一条线程,虽然我们写了两条线程,但是有三条线程同时执行。

package 多线程;
class A extends Thread{
	public void run(){
		while(true){
			System.out.println("aaaaaaaaa");
		}
	}
}
class B extends Thread{
	public void run(){
		while(true){
			System.out.println("11111111");
		}	
	}
}
public class Test {

	public static void main(String[] args) {
		A a=new A();
		B b=new B();
		a.start();//线程1
		b.start();//线程2
		while(true){//线程3
			System.out.println("*********");
		}
	}

}

输出时:
(111111111)
(aaaaaaa)
(***********)都会输出

2,实现runnable接口(注意要用Thread包装,比较常用)

package 多线程;
//线程1
class A implements Runnable{
//任务1
	public void run(){
		while(true){
			System.out.println("aaaaaaaaa");
		}
	}
}
class B implements Runnable{
	public void run(){
		while(true){
			System.out.println("11111111");
		}	
	}
}
public class Test {

	public static void main(String[] args) {
		A a=new A();
		B b=new B();
		Thread t1=new Thread(a);
		//启动线程前先要用Thread包装a,b
		Thread t2=new Thread(b);
		t1.start();
		t2.start();
	}
}

在这里插入图片描述
需要注意的是,此时注意this代表的是a对象而不是t1线程对象,因为虚拟机调用的是A里面的run方法,所以this代表run里面的a对象。
结果:
在这里插入图片描述
3,使用线程池:
使用线程池,可以确定所要开辟的线程数量,只需要改一个参数就可以了,非常方便。比如创建一个线程池,里面放三个线程
需要注意:ExecutorService是一个接口,不能直接new,所以这里需要一个匿名内部内来完成,需要重写接口里面的方法

ExecutorService es=Executors.newFixedThreadPool(3);
es.execute(new Runnable() {
			public void run() {
				//执行语句
			}
		});

注意:不是开启了三个线程,只执行前三个任务,而是前三个任务在线程下执行,第四个任务等着,如果前三个任务谁先执行完,就会让出线程,让第四个任务执行。但是前三个都是死循环,所以第四个任务不管如何都执行不到,可以把第一个任务写成for循环,等它执行完了,第四个任务就执行。

package 多线程;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test {
	public static void main(String[] args) {
		//创建了一个线程池,线程池里面就固定放了3个线程
		ExecutorService es=Executors.newFixedThreadPool(3);
		//线程1去执行任务
		es.execute(new Runnable() {
			public void run() {
				for (int i = 0; i < 10000; i++) {	
					System.out.println("11111111111111111111111");
				}
			}
		});
		//线程2去执行任务
				es.execute(new Runnable() {
					public void run() {
						while(true){
							System.out.println("aaaaaaaaaaaaaaaaa");
						}	
					}
				});
		//线程3去执行任务
		es.execute(new Runnable() {
					
			public void run() {
				while(true){
					System.out.println("#######################");
				}			
			}
		});
		//线程4去执行任务
				es.execute(new Runnable() {		
					public void run() {
						while(true){
							System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>");
							System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>");
							System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>");
							System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>");
						}			
					}
				});
	}
}

创建了一个线程池,线程池里面放了一个缓存的线程,就是你来几个任务我自动创建几个线程,自适应。

ExecutorService es=Executors.newCachedThreadPool();

有了这个,我们就可以任意增加线程,而不再改参数,自适应

package 多线程;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test {
	public static void main(String[] args) {
		ExecutorService es=Executors.newCachedThreadPool();
		es.execute(new Runnable() {
			public void run() {
				while(true){
					System.out.println("0000000000000");
				}	
			}
		});
		//线程2去执行任务
				es.execute(new Runnable() {
					public void run() {
						while(true){
							System.out.println("aaaaaaaaaaaaaaaaa");
						}	
					}
				});
		//线程3去执行任务
		es.execute(new Runnable() {
					
			public void run() {
				while(true){
					System.out.println("#######################");
				}			
			}
		});
		//线程4去执行任务
				es.execute(new Runnable() {		
					public void run() {
						while(true){
							System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>");
						}			
					}
				});
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_44699728/article/details/89880173