关于多线程的理解和原理(集合了一波别人的专业术语和自己的代码)
什么是多线程:
· 在一个程序中,一些独立运行的程序片断叫作“线程”(Thread),利用它编程的概念就叫作“多线程处理”。
多线程的基础原理
· 多线程是为了同步完成多项任务,不是为了提高运行效率,而是为了提高资源使用效率来提高系统的效率。线程是在同一时间需要完成多项任务的时候实现的。
线程
· 每个正在系统上运行的程序都是一个进程。每个进程包含一到多个线程。进程也可能是整个程序或者是部分程序的动态执行。线程是一组 指令的集合,或者是程序的特殊段,它可以在程序里独立执行。也可以把它理解为代码运行的上下文。所以线程基本上是轻量级的进程,它负责在单个程序里执行多任务。通常由操作系统负责多个线程的调度和执行。
· 线程是程序中一个单一的顺序控制流程.在单个程序中同时运行多个线程完成不同的工作,称为多线程.
· 线程和进程的区别在于,子进程和父进程有不同的代码和数据空间,而多个线程则共享数据空间,每个线程有自己的执行堆栈和程序计数器为其执行上下文.多线程主要是为了节约CPU时间,发挥利用,根据具体情况而定. 线程的运行中需要使用计算机的内存资源和CPU。
多线程有什么好处
· 使用线程可以把占据时间长的程序中的任务放到后台去处理
· 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度
· 程序的运行速度可能加快
· 在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下可以释放一些珍贵的资源如内存占用等等。
. 多线程技术在IOS软件开发中也有举足轻重的位置。
. 线程应用的好处还有很多,就不一一说明了
多线程有什么坏处
· 如果有大量的线程,会影响性能,因为操作系统需要在它们之间切换。
· 更多的线程需要更多的内存空间。
· 线程可能会给程序带来更多“bug”,因此要小心使用。
· 线程的中止需要考虑其对程序运行的影响。
· 通常块模型数据是在多个线程间共享的,需要防止线程死锁情况的发生。
测试多线程中常见的代码及意义
/**测试Thread中的常用方法
* 1.Start():启动当前线程,调用当前线程的run()
* 2.run():通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明再次方法中
* 3.currentThread():静态方法,返回当前代码执行的线程
* 4.getName();获取当前线程的名字
* 5.setName();设置当前线程的名字
* 6.yield();释放当前cpu的执行权
* 7.join();在线程a中调用线程B的join(),此时线程a就进入阻塞状态。直到线程b完全执行完,才结束阻塞状态
* 8.stop();强制线程生命期结束,已过时!
* 9.sleep(Long ,millitime);使线程根据规定的时间来运行
*
**/
附赠一下IDEA所需依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<repositories>
<repository>
<id>central</id>
<url>http://host:port/content/groups/public</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>http://host:port/content/groups/public</url>
</pluginRepository>
</pluginRepositories>
以下代码简单调用一下上面的方法及如何去使用方法
多线程测试创建MyThread类继承于Thread
/**多线程的创建方式一:继承与Thread类
* 1.创建一个继承与Thread的子类
* 2.重写Thread类的run() -->此线程执行的操作声明在Run()中
* 3.创建Thread类的子类的对象
* 4.通过此对象调用start()
*
* 例子“遍历100以内的所有偶数
*
*
*/
class MyThread extends Thread{
//重写Runf()
@Override
public void run() {
for (int i = 0;i < 100;i++){
if (i % 2 == 0) {
System.out.println(Thread.currentThread().getName()+";"+i);
}
}
}
}
public class ThreadTest{
public static void main(String[] args) {
//创建thread的子类对象
MyThread mt = new MyThread();
mt.start();//1启动当前线程,2调用当前线程的run()
//下面for是在另一个线程启动执行
for (int i = 0;i < 100;i++) {
if (i % 2 == 0) {
System.out.println(Thread.currentThread().getName()+";"+i);
}//问题:我们不能通过直接调用run()的方式启动线程
//问题: 在启动一个县城,遍历100以内的偶数,不可以还让已经Start()的线程去执行
//需要从新创建一个线程的对象,创建多个线程就要创建多个对象
}
}
}
创建ThreadDemo类
//创建两个分线程,其中一个线程遍历100以内的偶数,另一个线程遍历100以内的奇数
public class ThreadDemo {
public static void main(String[] args) {
// Thread1 t1 = new Thread1();
// Thread2 t2 = new Thread2();
// t1.start();
// t2.start();
//创建Thread类的匿名子类的方式
new Thread(){
@Override
public void run(){
for (int i = 0;i<100;i++){
if (i % 2 == 0){
System.out.println(Thread.currentThread().getName()+";"+i);
}
}
}
}.start();
new Thread(){
@Override
public void run(){
for (int i = 0;i<100;i++){
if (i % 2 != 0){
System.out.println(Thread.currentThread().getName()+";"+i);
}
}
}
}.start();
}
}
//class Thread1 extends Thread{
// @Override
// public void run(){
// for (int i = 0;i<100;i++){
// if (i % 2 == 0){
// System.out.println(Thread.currentThread().getName()+";"+i);
// }
// }
// }
//}
//class Thread2 extends Thread{
// @Override
// public void run(){
// for (int i = 0;i<100;i++){
// if (i % 2 != 0){
// System.out.println(Thread.currentThread().getName()+";"+i);
// }
// }
// }
//}
创建方法类HelloThread继承于Thread
class HelloThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if (i % 2 == 0) {
try {
sleep(1000);//括号内直接出入数字
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ";" + i);
}
// if (i % 20 == 0){
// this.yield();
// }
}
}
// public HelloThread1(String name){
// super(name);
// }
}
public class ThreadMethodTest {
public static void main(String[] args) {
// HelloThread5 h5 = new HelloThread5(name + "Thread:1");
HelloThread h1 = new HelloThread();
h1.setName("线程1");
h1.start();
//给主线程命名
Thread.currentThread().setName("主线程");
for (int i = 0; i < 100; i++) {
if (i % 2 != 0) {
System.out.println(Thread.currentThread().getName() + ";" + i);
}
if (i == 20){
try {
h1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}