Java 复习 —— 多线程基础

1、基本概念

1)进程:运行当中的程序,程序是静止的概念,进程的是动态的概念,进程与进程之间互不运影响

2)线程:指程序中单独顺序的流控制,线程依附于进程中,他是最小的执行单位!一个任务一个线程。

3)多线程:指的是单个程序中可以同时运行多个不同的线程,执行不同的任务。(本身就要把线程理解为为不同的任务而服务的)

4)二者关系:一个进程当中可以有一个或多个线程,但是至少有一个线程。

2、作用与关系

1)多线程的目的:最大限度利用CPU资源

2)主线程:Java程序默认启动一个线程就是main线程,也就是主线程。另外一定要注意main只是一个线程

不是进程,所以main退出不代表进程退出,想要进程退出必须所有线程都停止。

3)进程之间内部数据和状态是完全独立的,但是多线程则是共用寄存器的数据,所以多线程之间会相互影响,但是线程的切换比进程的切换资源负担较小。

4)多个进程的内部数据和状态是完全独立的,而多线程是共享一块内存空间的一组系统资源,相互之间会影响。

5)线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切换比进程的切换负担要小。

3、Java 线程定义

1)继承Thread类,重写run方法,启动时,new 一个实例调用实例的start方法

2)实现Runnable接口,实现run方法;new一个当前类的实例同时作为一个Thread实例的参数调用start

3)每个线程都会有一个名字,这个名字就线程的标识,但是这个标识不是唯一的,也就是可能有多个线程拥有同一个名字。

4)线程执行的代码写在run方法中,然后通过start方法启动线程,然后系统默认为我们调用run方法,这个start的作用就是为线程的执行准备资源,如果你手动调用run方法,那么这个时候启动的线程不是真正的线程。他其实就就是一个普通的方法,不再是以线程的概念运行。

5)对于start方法只能调用一次,而且线程运行完了之后,也不能重重新调用start,而是必须重新new一个线程实例重新调用start;多次调用start会抛出一个线程状态异常(运行是异常)。

6)对于单核多核只是决定并行线程个数的多少,多线程如果只是在单核里面,其实的他们运行的顺序是不受控制的,让人觉得多个线程同时执行(宏观并行),而实际上因为多线程是对CPU资源的竞争,所以,只要某个线程竞争到资源就能运行,多个线程相互竞争之中导致多个任务交叉执行,所以让人觉得多个线程同时执行!单核处理器同样可以运行多个线程,只是这些线程其实是串行(微观串行)的而非并行的,不过他们的执行顺序的确是不确定的,因为同一个时间单核的只能处理一个线程!但是对于多核则不一样,他是真正意义的微观并行,同一时间确实可以有多个线程执行!

4、Thread 与 Runnable 的关系

1)Thread类实现了Runnable接口,实现了run方法,具体实现就是对他的成员变量Runnable变量进行空判断,如果不为空就调用它的run方法,所以我们写一个继承Thread的类必须重新run方法。

2)Runnable是接口,Thread是类,Java单继承的特性决定了Runnable更容易扩展

3)一个Runnable变量可以被多个Thread实例共享,这个对于线程资源共享意义是重大的

5、线程暂停、停止

0)禁止使用stop方法停止线程,这个方法是一个不安全方法(核心就是抛异常的方式),同时也是一个depcrecated方法

1)旗标法停止线程,通过一个标识量来进行循环跳出,这个标识量可以是在循环外赋值,也可以是在循环内改变这个值(这个时候可以直接break、return);

2)使用interrupt的方式停止线程,这个也是不建议使用的,核心也是抛异常的方式,只是因为interrupt在线程处于阻塞状态被调用时会重置线程的interrupted值,从而导致值的不准确性,所以也是不建议使用!

3)通过sleep和yield方法暂停线程,这个是建议使用的,他们都不会释放对象的锁!

4)通过suspend 和 resume 来暂停唤醒线程 是不建议使用的,由于使用这两个方法可能会造成一些不可预料的事情发生,因此,这两个方法被标识为deprecated(弃用)标记,这表明在以后的jdk版本中这两个方法可能被删除!

6、线程生命周期

1)创建 :new 一个实例之后

2)可运行(就绪):调用了start,也就是就绪状态

3)运行状态:线程获取到CPU资源,正在处理

4)不可运行(挂起、阻塞) : 被阻塞,比如等待IO,等待对象锁等

5)消亡:线程运行完了,或抛了异常

注意,阻塞状态可分为如下几种情况:

A、 位于对象等待池中的阻塞状态:当线程运行时,如果执行了某个对象的wait()方法,java虚拟机就回把线程放到这个对象的等待池中。

B、 位于对象锁中的阻塞状态:当线程处于运行状态时,试图获得某个对象的同步锁时,如果该对象的同步锁已经被其他的线程占用,JVM就会把这个线程放到这个对象的琐池中。

C、 其它的阻塞状态:当前线程执行了sleep()方法,或者调用了其它线程的join()方法,或者发出了I/O请求时,就会进入这个状态中。

JDK源码中线程的状态:

A thread state. A thread can be in one of the following states:

  • NEW
    A thread that has not yet started is in this state.
  • RUNNABLE
    A thread executing in the Java virtual machine is in this state.
  • BLOCKED
    A thread that is blocked waiting for a monitor lock is in this state.
  • WAITING
    A thread that is waiting indefinitely for another thread to perform a particular action is in this state.
  • TIMED_WAITING
    A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.
  • TERMINATED
    A thread that has exited is in this state.

A thread can be in only one state at a given point in time. These states are virtual machine states which do not reflect any operating system thread states.

7、线程的优先级

1)如果有优先级的限定可能导致低优先级的线程永远都没有机会执行,这样是不合理的,所以线程的优先级是不能唯一决定的线程的执行的!操作系统会在程序运行时动态控制线程的优先级,比如这个线程等待的时间越长,那么他的优先级就会变高,这样才能保证所有的线程都有机会执行!所以程序员不应该过于依赖优先级来决定线程的执行!

2)设置优先级是为了在多线程环境中便于系统对线程的调度,优先级高线程将优先执行,但是并不建议使用优先级来控制线程的执行顺序;

3)线程创建时,子继承父的优先级

4)线程初始化之后,通过调用setPriority方法改变优先级

5)线程的优先级是1~10之间正整数

8、线程的调度

线程调度器选择优先级最高的线程运行。但是如果发生以下情况就会终止线程的运行:

A:线程体中调用了yield方法,让出了对CPU资源的占用权

B:线程体中调用了sleep方法,是线程处于休眠状态,也可能会让出对CPU资源的占用权

C:线程由于I/O操作而受阻塞,等其他阻塞状态都会导致原本占用的CPU资源被释放

D:在支持时间片的系统中,该线程的时间片用完

时间: 2024-08-05 01:48:43

Java 复习 —— 多线程基础的相关文章

java笔记--多线程基础

多线程技术 在java中实现多线程技术有两种方式: 1.继承Thread类: 2.实现Runnable接口 这两种方法都需要重写run()方法:通常将一个新线程要运行的代码放在run()方法中(这是创建没有返回值线程的方法)由于java只支持单继承,当类已经继承有其他类时,只能选择实现Runnable接口在启动线程时需要使用Thread类的start()方法,而不是直接使用run()方法: 如: public static void function() { for (int i = 0; i

java复习-多线程

和线程之间的关系: 进程:进程是程序的一次动态执行过程,他经理了代码加载,执行到执行完毕的一个完整过程,这个过程也是进程本身从产生,发展到最终消亡的过程. 线程:线程是实现并发机制的一种有效手段,进程和线程一样,都是实现并发的一个基本单元. java中多线程实现: 集成Thread和实现runnable 通过线程类的start方法来并发执行线程里面的线程主体内容. Runnable线程的执行方式如下: Thread是Runnable接口的子类. Thread类与Runnable接口的区别: 1

Java 复习 —— 多线程同步

1.问题引出 在多线程环境中,可能有多个线程同时访问一个有限的资源(资源共享),为了避免资源访问.操作混乱,所以出现了锁的机制!合理控制资源的操作(读与写)权限. 2.了解几个概念 1)获取CPU资源:线程想要执行必须得到CPU资源,这是一个必要条件!然而资源的调度是操作系统根据线程的优先级.线程资源的使用等因素来确定的.不需要深究,只要知道线程想要运行必须要获取到CPU资源,这是一个门槛.我们总是纠结Thread 的 sleep.yield.start 之后到底什么时候运行,其实就是CPU资源

java核心技术-多线程基础

进程.线程 ? 进程(Process) 是程序的运行实例.例如,一个运行的 Eclipse 就是一个进程.进程是程序向操作系统申请资源(如内存空间和文件句柄)的基本单位.线程(Thread)是进程中可独立执行的最小单位.一个进程可以包含多个线程.进程和线程的关系,好比一个营业中的饭店与其正在工作的员工之间的关系. 1.1 线程的创建.启动与运行 在 Java 中实现多线程主要用两种手段,一种是继承 Thread 类,另一种就是实现 Runnable 接口.(当然还有Callable和线程池).下

Java 复习 —— JMM基础

基本内容 1.共享变量在线程间的可见性 2.synchronized实现可见性 3.volatile 实现可见性 1)指令重排序 2)as-if-serial 3)volatile 使用注意事项 4.volatile和synchronized的比较 1.可见性 一个线程对共享变量值的修改,能够及时地被其他线程看到. 共享变量:如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量. Java内存模型(JMM):描述了Java程序中各种变量(共享变量)的访问规则,以及在

Java 复习 —— 语言基础

基础概念 1.标识符:由字母.下划线.数字.美元符号组成,但是不能以数字开头. 2.关键字:50个关键字,goto虽然不存在,但是依然是关键字 3.变量:其命名规范不一定是按照标识符来,其可以是中文等 数据类型 1.Java共8种原生数据类型(另外一种就是引用类型),可分为四组 1)逻辑类型:boolean 2)字符类型:char 3)浮点类型:float.double 4)整数类型:byte short int long 2.数据类型精度排序: byte(1).short(2).char(2)

Java复习——多线程与并发库

开启一个线程 实现一个线程的方式有两种:继承Thread类.实现Runnable接口.这两种方法都需要重写Run方法,具体的线程逻辑代码写在Run方法中.其实Thread类就实现了Runnable接口,但是并没有什么说法是使用哪种方式存在效率高低的问题,推荐使用实现Runnable接口的方式,因为更加面向对象,而且实现一个接口比继承一个类更灵活.我们可以使用匿名内部类的方式很方便的开启一个线程(使用Tread类的start方法开启一个线程): Thread : new Thread(){ pub

[Java复习] 多线程 并发 JUC 补充

线程安全问题? 当多个线程共享同一个全局变量,做写的操作时,可能会受到其他线程的干扰.读不会发生线程安全问题. --  Java内存模型. 非静态同步方法使用什么锁? this锁 静态同步方法使用什么锁? 当前类的字节码文件 什么是ThreadLocal? ThreadLocal是给每个线程提供局部变量,每个线程可独立改变自己的副本,不会影响其他线程所对应的副本,解决线程安全问题. ThreadLocal底层原理是map集合. ThreadLocal内存泄漏问题? 由于ThreadLocalMa

Java 复习 —— 多线程中断

1.interrupt中断线程 1.interrupt 会给wait池中的线程抛出异常,这个时候该线程会被唤醒,但是同样还要继续竞争锁资源,才能继续运行! 2.interrupt 会给正在sleep的线程抛出异常,但是不会给yield线程抛出异常,个人感觉是因为sleep是指定多长时间阻塞,但是yield的确是不知道至少多长时间阻塞,另外yield这个方法只在测试使用,开发当中少用. 3.如果线程在调用 Object 类的 wait().wait(long) 或 wait(long, int)