首先,要辨析进程与线程的概念:

  进程是程序执行的过程,它持有资源和线程,相对于程序本身而言具有动态性。

  线程是系统中最小的执行单元,同一个进程中可能有多个线程,它们共享该进程持有的资源。线程的通信也称为线程的交互,方式主要有互斥和同步。同步是指线程之间通过共同协作完成某项工作,线程间具有次序性;互斥是指线程间对某一资源的竞争,一次只能有一个线程访问该资源。

  介绍完了这些基本概念,下面简单介绍一下Java对多线程的支持.

  java中通过类Thread和接口Runnable来实现多线程的操作。它们都有一个run方法来指定线程工作时执行的代码。

Thread类的常用方法

类别

名称

简介

线程的创建

Thread()

 

Thread(String name)

Thread(Runnable target)

Thread(Runnable target, String name)

线程的方法

void start()

启动线程

static void sleep(long millis)

线程休眠

static void sleep(long millis, int nanos)

void join()

某线程调用join方法后,使其他线程等待该线程终止

void join(long millis)

void join(long millis, int nanos)

static void yield()

当前正在运行的线程立刻释放处理器,重新加入竞争处理器的队列

获取线程引用

static Thread currentThread()

返回当前正在运行的线程的引用

  使用多线程有两种方式,一种是直接继承Thread类,一种是实现Runnable接口

  • 继承Thread类,在run方法中指定需要线程执行的代码,通过getName()和setName()方法去访问线程名称。通过该类对象的start方法来开启线程。
  • 实现Runnable接口,重写run方法来指定需要线程执行的代码,然后把该类的对象作为参数传递给Thread对象来执行。

  另外,通过volatile关键字声明的成员变量可以保证当其他线程修改该成员变量后,本线程可以正确读取到此成员变量的值。

线程的状态

  请结合OS中进程的5态来思考。以下线程状态和方法的介绍来自DreamSea(张小哲)

  • 新生状态(New): 当一个线程的实例被创建即使用new关键字和Thread类或其子类创建一个线程对象后,此时该线程处于新生(new)状态,处于新生状态的线程有自己的内存空间,但该线程并没有运行,此时线程还不是活着的(not alive);
  • 就绪状态(Runnable): 通过调用线程实例的start()方法来启动线程使线程进入就绪状态(runnable);处于就绪状态的线程已经具备了运行条件,但还没有被分配到CPU即不一定会被立即执行,此时处于线程就绪队列,等待系统为其分配CPCU,等待状态并不是执行状态; 此时线程是活着的(alive);
  • 运行状态(Running): 一旦获取CPU(被JVM选中),线程就进入运行(running)状态,线程的run()方法才开始被执行;在运行状态的线程执行自己的run()方法中的操作,直到调用其他的方法而终止、或者等待某种资源而阻塞、或者完成任务而死亡;如果在给定的时间片内没有执行结束,就会被系统给换下来回到线程的等待状态;此时线程是活着的(alive);
  • 阻塞状态(Blocked):通过调用join()、sleep()、wait()或者资源被暂用使线程处于阻塞(blocked)状态;处于Blocking状态的线程仍然是活着的(alive)
  • 死亡状态(Dead):当一个线程的run()方法运行完毕或被中断或被异常退出,该线程到达死亡(dead)状态。此时可能仍然存在一个该Thread的实例对象,当该Thread已经不可能在被作为一个可被独立执行的线程对待了,线程的独立的call stack已经被dissolved。一旦某一线程进入Dead状态,他就再也不能进入一个独立线程的生命周期了。对于一个处于Dead状态的线程调用start()方法,会出现一个运行期(runtime exception)的异常;处于Dead状态的线程不是活着的(not alive)。

Ø线程的方法(Method)、属性(Property)

1)优先级(priority)

每个类都有自己的优先级,一般property用1-10的整数表示,默认优先级是5,优先级最高是10;优先级高的线程并不一定比优先级低的线程执行的机会高,只是执行的机率高;默认一个线程的优先级和创建他的线程优先级相同;

2)Thread.sleep()/sleep(long millis)

当前线程睡眠/millis的时间(millis指定睡眠时间是其最小的不执行时间,因为sleep(millis)休眠到达后,无法保证会被JVM立即调度);sleep()是一个静态方法(static method) ,所以他不会停止其他的线程也处于休眠状态;线程sleep()时不会失去拥有的对象锁。 作用:保持对象锁,让出CPU,调用目的是不让当前线程独自霸占该进程所获取的CPU资源,以留一定的时间给其他线程执行的机会;

3)Thread.yield()

让出CPU的使用权,给其他线程执行机会、让同等优先权的线程运行(但并不保证当前线程会被JVM再次调度、使该线程重新进入Running状态),如果没有同等优先权的线程,那么yield()方法将不会起作用。

4)thread.join()

使用该方法的线程会在此之间执行完毕后再往下继续执行。

5)object.wait()  当一个线程执行到wait()方法时,他就进入到一个和该对象相关的等待池(Waiting Pool)中,同时失去了对象的机锁—暂时的,wait后还要返还对象锁。当前线程必须拥有当前对象的锁,如果当前线程不是此锁的拥有者,会抛出IllegalMonitorStateException异常,所以wait()必须在synchronized block中调用。sleep()和wait()方法的最大区别是:sleep()睡眠时,保持对象锁,仍然占有该锁;而wait()睡眠时,释放对象锁。但是wait()和sleep()都可以通过interrupt()方法打断线程的暂停状态,从而使线程立刻抛出InterruptedException(但不建议使用该方法)。

6)object.notify()/notifyAll()

唤醒在当前对象等待池中等待的第一个线程/所有线程。notify()/notifyAll()也必须拥有相同对象锁,否则也会抛出IllegalMonitorStateException异常。

7)Synchronizing Block

Synchronized Block/方法控制对类成员变量的访问;Java中的每一个对象都有唯一的一个内置的锁,每个Synchronized Block/方法只有持有调用该方法被锁定对象的锁才可以访问,否则所属线程阻塞;机锁具有独占性、一旦被一个Thread持有,其他的Thread就不能再拥有(不能访问其他同步方法),方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。

正确停止Java线程

  非正确停止的方法:stop()

  要正确停止线程,应该使用正确的退出标记。正常情况下run方法执行完毕线程就停止了,但是有些情况下run方法中需要while循环保持轮询,所以应该为while循环设置合适的退出条件,即退出标记,保证线程正确停止。

  或者使用interrupt()方法的初衷并不是要停止线程,正常情况下,调用该方法可以将中断标记设置为TRUE。但是,当某个线程因为调用了wait()或者sleep()等方法而被阻塞时,此时调用interrupt()方法并不能正确的将interrupted标记设置为TRUE,并且同时会抛出中断异常。

争用条件:当多个线程同时共享访问同一个内存数据时,每个线程都尝试操作该数据,从而导致数据被破坏。

线程的互斥与同步

互斥是指在同一时刻只有一个线程可以对临界区进行操作。在JAVA中,可以通过synchronized块或者方法来实现。

在synchronized块中,需要对某个对象进行加锁,并将需要互斥的代码放入synchronized块中,从而来实现互斥行为。获得该锁的进程可以进入该synchronized块中.

而同步则是线程之间的一种通信机制,通过同步可以规定线程执行的顺序。例如,当线程不满足访问某资源时,可以通过调用锁对象的lock.wait()方法,使该线程让出CPU,让出锁,并在该锁对象的waitset中等待。满足条件时,可以通过lock.notify()方法随机唤醒一条线程,lock.notifyAll()则唤醒该waitset中所有的线程,使它们重新竞争该锁。被唤醒的线程从wait()方法处继续执行。

Java基础之多线程简述的更多相关文章

  1. Java基础技术多线程与并发面试【笔记】

    Java基础技术多线程与并发 什么是线程死锁? ​死锁是指两个或两个以上的进程(线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去,我们就可以称 ...

  2. 关于java基础、多线程、JavaWeb基础、数据库、SSM、Springboot技术汇总

    作者 : Stanley 罗昊 本人自行总结,纯手打,有疑问请在评论区留言 [转载请注明出处和署名,谢谢!] 一.java基础 1.多态有哪些体现形式? 重写.重载 2. Overriding的是什么 ...

  3. Java基础之多线程篇(线程创建与终止、互斥、通信、本地变量)

    线程创建与终止 线程创建 Thread类与Runnable接口的关系 public interface Runnable { public abstract void run(); } public ...

  4. Java基础之多线程框架

    一.进程与线程的区别 1.定义: 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比 ...

  5. Java基础之多线程详细分析

    在了解多线程之前,先来了解一下进程与线程之间的关系. 进程和线程: 进程是指在系统中正在执行的一个程序,每个进程之间是独立的. 线程是进程的一个基本执行单元.一个进程要想执行任务,必须得有线程(每1个 ...

  6. java基础知识 多线程

    package org.base.practise9; import org.junit.Test; import java.awt.event.WindowAdapter; import java. ...

  7. Java基础之多线程

    1.进程和线程: 进程:正在进行的程序.每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元. 线程:进程内部的一条执行路径或者一个控制单元. 两者的区别: 一个进程至少有一个线程 ...

  8. 黑马程序员——【Java基础】——多线程

    ---------- android培训.java培训.期待与您交流! ---------- 一.概述 (一)进程 正在执行中的程序,每一个进程执行都有一个执行顺序.该顺序是一个执行路径,或者叫一个控 ...

  9. 黑马程序员——JAVA基础之多线程的线程间通讯等

    ------- android培训.java培训.期待与您交流! ---------- 线程间通讯: 其实就是多个线程在操作同一个资源,但是动作不同. wait(); 在其他线程调用此对象的notif ...

随机推荐

  1. 【sqli-labs】 less40 GET -Blind based -String -Stacked(GET型基于盲注的堆叠查询字符型注入)

    提交,页面正常,说明是')闭合的 http://192.168.136.128/sqli-labs-master/Less-40/?id=1')%23 http://192.168.136.128/s ...

  2. 子元素设置margin-top作用到了父元素

    子元素设置margin-top,父元素也受影响 解决办法:给父元素加个padding或border或overflow:hidden或父元素加前置内容生成 CSS中盒模型的理解

  3. apicloud 注意事项

    页面布局时头部和内容一定要分开,状态栏寖入式要用.可以用api.sendEvent广播出去,api.addlisterten监听. api.openWin打开页面会有黑色闪屏,加bgColor:'#f ...

  4. 如何手动触发物理机panic,并产生vmcore

    如何手动触发物理机panic,并产生vmcore? 1. 配置kdump 1.1 el6 如果是CentOS 6 则编辑/boot/grub/grub.conf配置在内核参数中添加 crashkern ...

  5. 06.系统编程-4.多线程和GIL

    为什么有人会说 Python? 多线程是鸡肋?知乎上有人提出这样一个问题,在我们常识中,多进程.多线程都是通过并发的方式充分利用硬件资源提高程序的运行效率,怎么在 Python 中反而成了鸡肋? 有同 ...

  6. 把 Python 脚本打包成可以直接双击运行的 .exe 文件 【转】

    因为最近要用到 Python 脚本,所以自己学习了一下,顺便学习如何把它打包成 .exe 可执行文件,达到双击运行的效果,网上找了资料,保存下来学习用,原文出处:https://baijiahao.b ...

  7. HDU 1466

    经典DP,这样的递推确实有点难. 把所有直线分成两组,可以知道 m条直线的交点方案数 =(m-r)条平行线与r条直线交叉的交点数  + r条直线本身的交点方案 亦就是  =(m-r)*r+r条之间本身 ...

  8. [Javascript] Highlights from IO18 Javascript new features

    Latest Javascript features, not supported by all broswers, but can use with babel. # try-catch-final ...

  9. android 点击返回键退出程序的方法

    android 点击返回键退出程序的方法 第一种: 再按一次返回键退出程序 private long exitTime = 0; @Override public boolean onKeyDown( ...

  10. Codeforces Round #313 (Div. 2) 560D Equivalent Strings(dos)

    D. Equivalent Strings time limit per test 2 seconds memory limit per test 256 megabytes input standa ...