首页 > 其他分享 >多线程

多线程

时间:2022-12-23 22:23:06浏览次数:39  
标签:Thread mc t2 t1 线程 多线程

多线程

什么是进程?什么是线程?
进程是一个应用程序(1个进程是一个软件)。
线程是一个进程中的执行场景/执行单元。
一个进程可以启动多个线程。

对于java程序来说,当在DOS命令窗口中输入:
java HelloWorld 回车之后。
会先启动JVM,而JVM就是一个进程。
JVM再启动一个主线程调用main方法。
同时再启动一个垃圾回收线程负责看护,回收垃圾。
最起码,现在的java程序中至少有两个线程并发,
一个是垃圾回收线程,一个是执行main方法的主线程。

进程和线程是什么关系?举个例子

​ 阿里巴巴:进程
​ 马云:阿里巴巴的一个线程
​ 童文红:阿里巴巴的一个线程

​ 京东:进程
​ 强东:京东的一个线程
​ 妹妹:京东的一个线程

​ 进程可以看做是现实生活当中的公司。
​ 线程可以看做是公司当中的某个员工。

​ 注意:
​ 进程A和进程B的内存独立不共享。(阿里巴巴和京东资源不会共享的!)
​ 魔兽游戏是一个进程
​ 酷狗音乐是一个进程
​ 这两个进程是独立的,不共享资源。

​ 线程A和线程B呢?
​ 在java语言中:
​ 线程A和线程B,堆内存和方法区内存共享。
​ 但是栈内存独立,一个线程一个栈。

​ 假设启动10个线程,会有10个栈空间,每个栈和每个栈之间,
​ 互不干扰,各自执行各自的,这就是多线程并发。

​ 火车站,可以看做是一个进程。
​ 火车站中的每一个售票窗口可以看做是一个线程。
​ 我在窗口1购票,你可以在窗口2购票,你不需要等我,我也不需要等你。
​ 所以多线程并发可以提高效率。

​ java中之所以有多线程机制,目的就是为了提高程序的处理效率。

思考一个问题:
使用了多线程机制之后,main方法结束,是不是有可能程序也不会结束。
main方法结束只是主线程结束了,主栈空了,其它的栈(线程)可能还在
压栈弹栈。

分析一个问题:对于单核的CPU来说,真的可以做到真正的多线程并发吗?

​ 对于多核的CPU电脑来说,真正的多线程并发是没问题的。
​ 4核CPU表示同一个时间点上,可以真正的有4个进程并发执行。

​ 什么是真正的多线程并发?
​ t1线程执行t1的。
​ t2线程执行t2的。
​ t1不会影响t2,t2也不会影响t1。这叫做真正的多线程并发。

​ 单核的CPU表示只有一个大脑:
​ 不能够做到真正的多线程并发,但是可以做到给人一种“多线程并发”的感觉。
​ 对于单核的CPU来说,在某一个时间点上实际上只能处理一件事情,但是由于
​ CPU的处理速度极快,多个线程之间频繁切换执行,跟人来的感觉是:多个事情
​ 同时在做!!!!!
​ 线程A:播放音乐
​ 线程B:运行魔兽游戏
​ 线程A和线程B频繁切换执行,人类会感觉音乐一直在播放,游戏一直在运行,
​ 给我们的感觉是同时并发的。

​ 电影院采用胶卷播放电影,一个胶卷一个胶卷播放速度达到一定程度之后,
​ 人类的眼睛产生了错觉,感觉是动画的。这说明人类的反应速度很慢,就像
​ 一根钢针扎到手上,到最终感觉到疼,这个过程是需要“很长的”时间的,在
​ 这个期间计算机可以进行亿万次的循环。所以计算机的执行速度很快。

java语言中,实现线程有两种方式,那两种方式呢?

java支持多线程机制。并且java已经将多线程实现了,我们只需要继承就行了。

第一种方式:编写一个类,直接继承java.lang.Thread,重写run方法。
// 定义线程类
public class MyThread extends Thread{
public void run(){

	}
}
// 创建线程对象
MyThread t = new MyThread();
// 启动线程。
t.start();

第二种方式:编写一个类,实现java.lang.Runnable接口,实现run方法。
// 定义一个可运行的类
public class MyRunnable implements Runnable {
public void run(){

	}
}
// 创建线程对象
Thread t = new Thread(new MyRunnable());
// 启动线程
t.start();

注意:第二种方式实现接口比较常用,因为一个类实现了接口,它还可以去继承
其它的类,更灵活。

6、关于线程对象的生命周期?
新建状态
就绪状态
运行状态
阻塞状态
死亡状态

1、(这部分内容属于了解)关于线程的调度

1.1、常见的线程调度模型有哪些?

​ 抢占式调度模型:
​ 那个线程的优先级比较高,抢到的CPU时间片的概率就高一些/多一些。
​ java采用的就是抢占式调度模型。

​ 均分式调度模型:
​ 平均分配CPU时间片。每个线程占有的CPU时间片时间长度一样。
​ 平均分配,一切平等。
​ 有一些编程语言,线程调度模型采用的是这种方式。

1.2、java中提供了哪些方法是和线程调度有关系的呢?

​ 实例方法:
​ void setPriority(int newPriority) 设置线程的优先级
​ int getPriority() 获取线程优先级
​ 最低优先级1
​ 默认优先级是5
​ 最高优先级10
​ 优先级比较高的获取CPU时间片可能会多一些。(但也不完全是,大概率是多的。)

​ 静态方法:
​ static void yield() 让位方法
​ 暂停当前正在执行的线程对象,并执行其他线程
​ yield()方法不是阻塞方法。让当前线程让位,让给其它线程使用。
​ yield()方法的执行会让当前线程从“运行状态”回到“就绪状态”。
​ 注意:在回到就绪之后,有可能还会再次抢到。

​ 实例方法:
​ void join()
​ 合并线程
​ class MyThread1 extends Thread {
​ public void doSome(){
​ MyThread2 t = new MyThread2();
​ t.join(); // 当前线程进入阻塞,t线程执行,直到t线程结束。当前线程才可以继续。
​ }
​ }

​ class MyThread2 extends Thread{

​ }

2、关于多线程并发环境下,数据的安全问题。

2.1、为什么这个是重点?
以后在开发中,我们的项目都是运行在服务器当中,
而服务器已经将线程的定义,线程对象的创建,线程
的启动等,都已经实现完了。这些代码我们都不需要
编写。

​ 最重要的是:你要知道,你编写的程序需要放到一个
​ 多线程的环境下运行,你更需要关注的是这些数据
​ 在多线程并发的环境下是否是安全的。(重点:*****)

2.2、什么时候数据在多线程并发的环境下会存在安全问题呢?
三个条件:
条件1:多线程并发。
条件2:有共享数据。
条件3:共享数据有修改的行为。

​ 满足以上3个条件之后,就会存在线程安全问题。

2.3、怎么解决线程安全问题呢?
当多线程并发的环境下,有共享数据,并且这个数据还会被修改,此时就存在
线程安全问题,怎么解决这个问题?
线程排队执行。(不能并发)。
用排队执行解决线程安全问题。
这种机制被称为:线程同步机制。

​ 专业术语叫做:线程同步,实际上就是线程不能并发了,线程必须排队执行。

​ 怎么解决线程安全问题呀?
​ 使用“线程同步机制”。

​ 线程同步就是线程排队了,线程排队了就会牺牲一部分效率,没办法,数据安全
​ 第一位,只有数据安全了,我们才可以谈效率。数据不安全,没有效率的事儿。

2.4、线程同步,两个专业术语:

​ 异步编程模型:
​ 线程t1和线程t2,各自执行各自的,t1不管t2,t2不管t1,
​ 谁也不需要等谁,这种编程模型叫做:异步编程模型。
​ 其实就是:多线程并发(效率较高。)

​ 异步就是并发。

​ 同步编程模型:
​ 线程t1和线程t2,在线程t1执行的时候,必须等待t2线程执行
​ 结束,或者说在t2线程执行的时候,必须等待t1线程执行结束,
​ 两个线程之间发生了等待关系,这就是同步编程模型。
​ 效率较低。线程排队执行。

​ 同步就是排队。


// 面试题:doOther方法执行的时候需要等待doSome方法的结束吗?
    //需要
public class Exam01 {
    public static void main(String[] args) throws InterruptedException {
        MyClass mc = new MyClass();

        Thread t1 = new MyThread(mc);
        Thread t2 = new MyThread(mc);

        t1.setName("t1");
        t2.setName("t2");

        t1.start();
        Thread.sleep(1000); //这个睡眠的作用是:为了保证t1线程先执行。
        t2.start();
    }
}

class MyThread extends Thread {
    private MyClass mc;
    public MyThread(MyClass mc){
        this.mc = mc;
    }
    public void run(){
        if(Thread.currentThread().getName().equals("t1")){
            mc.doSome();
        }
        if(Thread.currentThread().getName().equals("t2")){
            mc.doOther();
        }
    }
}

class MyClass {
    public synchronized void doSome(){
        System.out.println("doSome begin");
        try {
            Thread.sleep(1000 * 10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("doSome over");
    }
    public synchronized void doOther(){
        System.out.println("doOther begin");
        System.out.println("doOther over");
    }
}
// 面试题:doOther方法执行的时候需要等待doSome方法的结束吗?
    //需要
public class Exam01 {
    public static void main(String[] args) throws InterruptedException {
        MyClass mc = new MyClass();

        Thread t1 = new MyThread(mc);
        Thread t2 = new MyThread(mc);

        t1.setName("t1");
        t2.setName("t2");

        t1.start();
        Thread.sleep(1000); //这个睡眠的作用是:为了保证t1线程先执行。
        t2.start();
    }
}

class MyThread extends Thread {
    private MyClass mc;
    public MyThread(MyClass mc){
        this.mc = mc;
    }
    public void run(){
        if(Thread.currentThread().getName().equals("t1")){
            mc.doSome();
        }
        if(Thread.currentThread().getName().equals("t2")){
            mc.doOther();
        }
    }
}

class MyClass {
    public synchronized void doSome(){
        System.out.println("doSome begin");
        try {
            Thread.sleep(1000 * 10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("doSome over");
    }
    public synchronized void doOther(){
        System.out.println("doOther begin");
        System.out.println("doOther over");
    }
}

标签:Thread,mc,t2,t1,线程,多线程
From: https://www.cnblogs.com/LDCnc-lili/p/17001748.html

相关文章

  • 【并发技术系列】「多线程并发编程」技术体系和并发模型的基础探究(夯实基础)
    让我们通过本篇文章一同进入并发编程技术的世界里面,相信通过这篇文文章一定会对话你的并发技术体系有一定帮助以及夯实你的基础功底。基本概念并发concurrency并行paralleli......
  • jdk 1.8 多线程
    packagecom.sleep.demo;importorg.springframework.util.CollectionUtils;importjava.util.ArrayList;importjava.util.List;importjava.util.Random;import......
  • Java多线程
    核心概念线程就是独立的执行路径在程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程,gc线程。main()称之为主线程,为系统的入口,用于执行整个程序;在一个进程......
  • 一、【Java】多线程与高并发
    一、启动多线程的三种方式1、继承Thread接口类实现run()方法staticclassMyThredextendsThread{@Overridepublicvoidrun(){system.out.println("Hellow......
  • 多线程原理和常用方法以及Thread和Runnable的区别
    多线程原理随机性打印CPU有了两条执行的路径,CPU就有了选择,一会执行main方法一会执行run方法。也可以说两个线程,一个main线程一个run线程一起请求CPU的执行权(执行......
  • 多线程下载USGS Lidar Explorer Map点云数据
    1.简介美国地质勘探局(UnitedStatesGeologicalSurvey,简称USGS),是美国内政部所属的科学研究机构。负责对自然灾害、地质、矿产资源、地理与环境、野生动植物信息等方......
  • 谈谈这几个常见的多线程面试题
    创建线程有几种不同的方式?你喜欢哪一种?为什么?有三种方式可以用来创建线程:继承Thread类实现Runnable接口应用程序可以使用Executor框架来创建线程池实现Runnab......
  • 内核多线程
    Linux内核多线程(一)Linux内核多线程(二)Linux内核多线程(三)Linux内核多线程(四)Linux内核多线程——补充(各种平台下的多线程) kernel_thread()和kthread_run()/kthread_cre......
  • 多线程实践篇
    这篇文章有参考ue5源码和其他源码。多线程同步.h文件/** *关键段用户模式下同步对象,除非竞争非常激烈,否则不会进入内核模式 */ classSYSTEM_APIMCriticalSection......
  • 多线程同步篇
    用户模式下的线程同步原子访问指的是一个线程在访问某个资源的同时能保证没有其他线程会在统一时刻访问同一资源。传入的变量必须是经过内存对齐的InterlockedExchang......