多线程简介
1.Process与Thread
- 程序本身是指定和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念。
- 而进程则是执行程序中的一次执行过程,是一个动态的概念。是系统能够资源分配的单位。
- 通常在一个进程里,可以包含若干个线程,当然一个进程至少有一个线程,不然没有存在的意义。
- 线程是CPU调度和执行的单位,线程是独立的执行路径
注:很多的多线程是模拟出来的,真正的多线程是指有多个cpu,即多核,如服务器。如果模拟出来的多线程,即在一个cpu的情况下,在同一个时间点,cpu只能执行一个代码,因为切换的很快,所有就有同时执行的错觉
- 在程序运行时,及时没有为自己创建线程,后台也会有多个线程,如主线程,gc线程等。
- main()称为主线程,为系统的入口,用于执行整个程序
- 在一个线程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作系统紧密相关的,先后顺序是不能人为的干预的。
- 对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制。
- 线程会带来额外的开销,如cpu调度时间,并发控制开销
- 每个线程在自己的工作内存交互,内存控制不当会造成数据不一致
- 对现在的程序来说至少需要两个线程,一个是执行main方法的主线程,一个垃圾回收(gc)线程.
2.线程的创建
我们现在一共有三种方式创建线程,分别是继承Threa类,
2.1通过继承Thread类创建
//创建方式一:继承Thread类,重写run()方法,调用start开启线程
package com.thread;
public class ThreadTest01 {
public static void main(String[] args) {
MyThread01 myThread01 = new MyThread01();
myThread01.start();
//start()方法的作用是:启动一个分支线程,在JVM中开辟一个新的栈空间,这段代码在任务完成之后,瞬间就结束了
//这段代码的任务只是为了开启一个新的栈空间,只要新的栈空间开出来,start ()方法就结束了,线程就启动成功了
//启动成功的线程会自动调用run方法,并且run方法在分支线的栈底部(压线)
//run()方法在分支栈的栈底部,man方法在主栈的栈底部,run和main是平级的
//muThread01.run;不会启动线程,不会分配新的分支线(这就是单线程)
for (int i = 0; i < 100; i++) {
System.out.println(\"主线程\"+i);
}
}
static class MyThread01 extends Thread{
@Override
public void run() {
//编写程序,这段程序运行在分支线程中
for (int i = 0; i < 100; i++) {
System.out.println(\"分支线程\"+i);
}
}
}
输出:因为输出较多,我们截取一部分,可以看出,是交替执行的。
主线程8
分支线程68
分支线程69
主线程9
分支线程70
分支线程71
分支线程72
分支线程73
分支线程74
分支线程75
分支线程76
主线程10
分支线程77
主线程11
分支线程78
主线程12
分支线程79
主线程13
分支线程80
主线程14
分支线程81
主线程15
主线程16
分支线程82
主线程17
线程开启不一定立即执行,是由cpu安排调度的
2.2编写一个类实现java.lang.Runnable接口
代码示例:
public class ThreadTest03 {
public static void main(String[] args) {
//创建线程对象
Thread t = new Thread(new MyRunnable());
//启动线程
t.start();
for (int i = 0; i < 100; i++) {
System.out.println(\"主线程\"+i);
}
}
//这并不是一个线程类,是一个可运行的类,还不是一个线程
static class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(\"分支线程\"+i);
}
}
}
}
部分输出结果:
分支线程31
分支线程32
主线程45
主线程46
主线程47
主线程48
主线程49
主线程50
主线程51
主线程52
主线程53
主线程54
主线程55
主线程56
主线程57
主线程58
主线程59
主线程60
主线程61
分支线程33
分支线程34
分支线程35
分支线程36
分支线程37
分支线程38
分支线程39
注:第二种方式实现接口比较常见,因为一个类实现了皆可以,还可以去继承其它的类,更加灵活!
3.多线程并发
-
进程与进程之间的内存独立不共享
-
在一个进程中,线程和线程的堆内存和方法区内存共享。但是栈内存独立,一个线程一个栈
假设启动十个线程,就会有十个栈空间,每个栈与每个栈之间,互不干扰,各自执行,这就是多线程并发
本文来自博客园,作者:星余明,转载请注明原文链接:https://www.cnblogs.com/lingstar/p/16529082.html
来源:https://www.cnblogs.com/lingstar/p/16529082.html
本站部分图文来源于网络,如有侵权请联系删除。