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

定义方式:

123
(锁对象) {代码块}

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

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

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

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

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

同步方法如何定义?

  • 解答:

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

同步方法注意事项:

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

线程安全问题

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

  • 解决方法

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

  • 注意事项

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

以前线程安全类的回顾

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

线程安全方法

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

  • ps:
    它的作用是传入一个集合对象,传出一个线程安全的集合对象

原文地址:https://www.cnblogs.com/lijianming180/p/12041115.html

时间: 2024-08-28 07:02:44

javaSE复习之——线程的相关文章

JAVASE复习

top 暑假每天中午更新 六花酱赛高 目录: 内部类 枚举类 垃圾回收 修饰符 与运行环境交互 内部类: 1. 外部类可以通过非静态内部类对象访问内部类的private属性,内部类可以直接访问外部类的private属性,说明外部类和内部类都是在“一个类中”,这样才能相互访问到对方的private属性 2. 非静态内部类的实例化:new Outer().new Inner();//这个很好理解,Inner需要用outer对象来实例化,Inner的命名空间是Outer 3. 静态内部类的实例化: n

体系结构复习4——线程级并行

体系结构复习 CH7 线程级并行 7.1 多处理器与线程级并行 7.1.1 多处理器体系结构 线程级并行是多处理器支持多个线程同时并行执行,多处理器体系结构大致分成两种: 对称共享存储器多处理器(SMP):又叫集中式共享存储器体系结构,核心数目较小并共享一个集中式的存储器,所有处理器能够平等地访问它(又称为UMA,一致存储器访问):SMP的存储结构大致分成三层:共享主存.共享缓存和专用缓存,本章最重要的讨论即是专用缓存和共享存储之间的一致性问题. 分布式共享存储(DSM):多处理采用物理分布式存

个人JAVASE复习笔记

集合 6.28 Arraylist 使用迭代器遍历的时候不能操作  目标 (改变集合元素的个数)除非特有方法,迭代器中提供的方法 其他遍历正在进行时也  尽量不要去操作目标,容易出错 java.util.ConcurrentModificationException (并发修改异常) 中途了解 迭代器 原理以及源码 个人解决  使用了 toArray() 转成 数组操作 (也许以后有更好的方法 期待) 6.29因此 了解到了  并发容器 COW , 6.30还有 线程安全的List list =

JavaSE复习总结之集合(Collection)

Java早期版本只给集合类库提供了很少的一组类,但是随着Java版本的升级,Java集合类库越来越充实.集合类库里面存放的,是各式各样的数据容器,我们基本都学过数据结构这门课,数据结构所讲的就是ADT(抽象数据模型)的部分,数据结构不是针对于某一门语言,它所讲的通常是对各语言都通用的ADT部分,ADT和具体实现是没有关系的.但是根据教材.根据各专业的不同,各专业会选用使用不同编程语言实现的教材.而我们所讲的,就是如何使用Java数据容器,即Java集合(用Java实现的ADT),具体的实现部分,

JavaSE 复习

这里分享一下学JavaSE 用的教材 高宏静的 <Java从入门到精通>,每一章都是一个单独的PDF用来复习JavaSE该是够了. 链接: http://pan.baidu.com/s/1ntyrDMx 密码: 6htz

JavaSE复习一

一.属性和局部变量的相同点和不同点 `1.1 相同点:都是声明在类的内部 1.2 不同点:属性在方法外,局部变量在方法内. 属性是跟随类创建的时候一起创建,而局部变量只有在类调用的时候才会开辟相应的内存空间进行创建. 二.Object类 2.1 equals的使用: Person类 public class Person { private String name; private int age; public String getName() { return name; } public

JavaSE复习_10 多线程复习

△wait()和sleep()的区别:  1.wait():没有等待时间,而sleep()需要有等待时间作为参数.  2.在同步中对于CPU的执行权和锁的处理不同:   wait()会释放执行权和锁.醒来后需要重新竞争锁.   sleep():释放执行权和,不会释放锁 void show(){ Synchronized(this){ wait() //可以同时有三个线程在此等待.只有拿到锁后,才能继续向下运行 } } void start(){ notifyAll(); //唤醒后,三个线程都具

JavaSE复习_2 对象与类

△java中的制表符.'\t'制表符."\t"也可以. △方法内不能再定义一个方法,互相平级. △数组中boolean类型的变量默认为false;char默认为'\u0000'(\u是unicode 的一种标识,标识16进制) △int [ ]a=new int[4]{1,2,3,4};非法 int [ ]a=new int[]{1,2,3,4};合法 int [ ]a=new int[]{1,2,3,4};可以在不同行,先声明,后赋值如: int [ ]a; a=new int[ ]

JavaSE复习日记 : Java操作符\关系运算符\逻辑运算符\赋值运算符\字符串连接符\三元运算符

// Java操作符\关系运算符\逻辑运算符\赋值运算符\字符串连接符\三元运算符 /* * 一 Java操作符 * * Java操作符都有哪些? * +, -, *, /, %, ++, -- * 这里需要注意 a++ 和 ++a 的区别,后面说; */ /* public class Javase{ public static void main(String[] args){ int a = 10; int b = 20; int c = 30; System.out.println( a