zoukankan      html  css  js  c++  java
  • javaSE复习之——线程

    线程其实就是程序执行的一条路径,一个进程中可以包含多条线程,多线程并发执行可以提高程序效率,可以同使完成多项任务

    多线程的应用场景

    • 迅雷多线程一起下载
    • 服务器同时处理多个客户请求

    多线程原理(单核CPU)

    在电脑上运行多个程序时,其实cpu一次只能做一个事,做一段时间后然后换另一个另一个做一段时间,只是cpu的速度太快了,看起来就是同时做很多事,也就是说多线程其实只是表面上的多线程,底层cpu还是一次只能做一个事,但是这有个前提,那就是那个cpu是单核cpu,如果事多核cpu,那么就可以真正的达到并行

    多线程并行和并发的区别

    • 并行

      并行是两个任务同时运行,需要多核cpu,有多少核就可以并行多少任务。

    • 并发

      并发是两个任务都请求运行,而一个处理器只能接受一个任务,就安排两个任务轮流进行,由于时间比较段短就感觉两个任务是同时在运行

    • ps

      我们所谓的多线程就是并发,如果不使用多线程,那么程序就是一句一句代码请求,如果使用了多线程,那么就可以这个方法请求运行,同时另一个方法也请求运行,也就是说,没有使用多线程的话代码是一条一条请求,使用了就是多条同时请求,但底层并不是并行,只是cpu处理太快了感觉不到。

    多线程程序实现方法1

    1、定义类继承Thread

    2、重写run方法

    3、把新线程要做的事写在run方法中

    4、创建线程对象,也就是我们定义的这个对象

    5、开启新的线程(start),内部会自动执行run方法

    多线程程序实现方法2

    1、定义类实现Runnable接口

    2、重写run方法

    3、把新线程要做的事卸载run方法中

    4、创建Thread对象,并且给它的构造方法传入一个实现了Runnable接口类的对象

    5、利用Thread开启新的线程

    多线程程序实现方法3

    • 第三种创建多线程的接口

      Callable

    • 创建方式:

      1、创建一个线程类,并且继承Callable<>类和重写call方法

      2、创建线程池

      3、创建线程对象然后用submit方法加入线程池即可

    两种实现多线程的区别(面试可能问)

    • 继承Thread:

      因为我们创建的类继承了Thread类,所以当我们调用start时,是直接执行子类的run方法,也就是我们创建的类。

    • 实现Runnable接口创建对象并传入实例化Thread的构造方法:

      我们是先创建实现了Runnable接口的对象,然后创建Thread对象并把之前创建的对象传入Thread构造方法,这时Thread类会把传入的对象保存到成员变量中,当我们调用Thread对象的start方法的时候,Thread对象会调用它的成员变量中的run方法,当然这个成员变量就是我们创建的那个实现了Runnable接口的对象

    两种实现多线程的好处与坏处

    • 继承Thread:

      • 好处:
        可以直接调用Thread中的方法,这样代码简洁。

      • 坏处:
        既然继承了Thread方法就不能继承其他类了

    • 实现Runnable接口:

      • 好处:
        因为接口是可以多实现的,所以可以继承其他父类

      • 坏处:
        不能直接创建对象使用,代码更加复杂

    • ps:

      个人感觉实现Runnable其实是继承Thread的一个补充,在开发时看情况使用。

    Thread类的方法

    • .start()

      开启线程,多次启动是非法的

    • .getName()

      获取线程名,默认线程名从Thread -0开始以此类推

    • .setName()

      设置线程名

    • .c 大专栏  javaSE复习之——线程urrentThread()

      获取当前线程对象的引用,在哪调用就获取哪的线程

    • .sleep(毫秒, 纳秒)

      休眠线程,传入多少时间就停多长时间,也可以单独传毫秒

    • .setDaemon()

      守护线程,设置一个线程为守护线程后,该线程不会单独执行,当其他非守护线程全部执行完之后自动退出。

      • ps:
        在非守护线程全部执行完毕后,会有一个缓冲时间,这个缓冲时间内守护线程还会运行,也就相当于非守护线程退出时会告诉守护线程可以退出了,这个告诉的时间就是缓冲时间
    • .join()

      调用此方法的线程暂停(写这句代码的线程),等待指定线程结束后,当前线程再继续运行

    • .join(int)

      等待指定的毫秒后继续执行

      • ps:
        如果在main主方法中调用t.join(),那么等待t这个线程执行结束之后,主方法才会继续执行,这个命令通常用在主方法中。
    • .yield()

      礼让线程,让出cpu,也就是让自己在cpu的执行优先级中降低,就是让别人先执行

    • .setPriority(1-10)

      设置线程优先级,默认是5

    • .getThreadGroup()

      通过线程对象获取它所属的组,返回线程组对象

    同步代码块的概述

    当有多条线程并发的时候,cpu会先执行完同步代码块中所有代码才会去执行另一个线程,不会这里执行几句代码那里执行几句代码

    • ps:
      它其实就是锁

    什么时候需要同步?

    当多线程并发,我们希望某个线程中某些代码执行过程中不切换到其他线程工作,我们就需要用到同步代码块。

    同步代码块关键字

    synchronized

    定义方式:

    1
    2
    3
    (锁对象) {
    代码块
    }

    同步代码块(锁)的注意事项:

    1、锁对象可以是任意的对象

    2、两个需要同步的代码块需要使用同一个锁,否则不能达到目标效果

    3、不能是匿名对象,因为两个匿名对象根本就不是一个对象,也就是不是同一把锁

    4、不要把锁进行嵌套,否则容易出现死锁,因为可能会出现互相等待的局面

    同步方法如何定义?

    • 解答:

      只要在修饰方法的时候加上synchronized关键字即可

    同步方法注意事项:

    • 非静态方法锁对象是它自己这个对象,也就是this
    • 静态方法因为它是随着类的加载而加载的,所以它的对象就是它所在类的字节码文件,也就是说静态方法的锁对象就是它所在类的字节码文件

    线程安全问题

    当多条线程操作同一个数据时,可能会出现数据安全问题

    • 解决方法

      在某一段需要判断并且操作数据地方加上一个同步代码块

    • 注意事项

      使用的锁对象一定要是同一个锁,建议直接用类的class文件,如果非要用引用数据类型,那么一定要用静态的。

    以前线程安全类的回顾

    线程安全的类涉及数据操作的方法都加了synchronized修饰,比如Vector、ArrayList,StringBuffer、StringBuilde

    线程安全方法

    .synchronized[这里可以后接集合类型,是什么类型就返回那个类型的集合]

    • ps:
      它的作用是传入一个集合对象,传出一个线程安全的集合对象
  • 相关阅读:
    Linux # $
    python英文学习字典
    python中read(),readline(),和readlines()
    if _name_ =="_main_"
    win10菜单打不开,任务栏右击没有反应
    python中csv转json文件出现:File was loaded in the wrong encoding: 'UTF-8'
    Python字典
    python 匿名函数实现求素数平方和
    Python快速排序的实现
    P1880 [NOI1995]石子合并
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12041115.html
Copyright © 2011-2022 走看看