`

Java 多线程

 
阅读更多

一、线程

1、程序:是一段静态的代码,它是应用软件执行的蓝本。

2、进程:是程序的一次动态执行过程,它对应了从代码的加载执行到执行完毕的一个完整过程。

3、线程:比进程更小的执行单位,一个进程在其执行过程中,可产生多个线程,形成多条执行线索,每条线索即每个线程,也有它自身的产生、存在与消亡的过程。

4、多线程编程的含义是:你可将程序的任务分成几个并行的子任务。特别是在网络中,你会发现很多功能是可以并发执行的。

5、多线程是与单线程相对而言的。

6、线程和进程的区别:

1)进程包括线程

2)进程都有一段专用的内存警戒(内存区域),子进程和父进程有不同的代码和数据空间。

3)多个线程共享数据空间,每个线程有自己的执行堆栈和程序计数器及执行上下文等。

4)多线程主要是为了节约CPU时间,提高效率。

7、新建的线程在它的一个完整的生命周期通常要经历5种状态:新建、就绪、运行、阻塞、死亡。

 

二、Sleep方法

1Thread类中有很多静态方法,这些方法都是在当前线程上运行的,即是在执行该方法的线程上运行的。

2、当线程处于空闲状态时,该线程必须将这个情况通知其他线程,以便其他线程有机会获得CPU控制权来运行自己的代码。

3Thread.sleep5);//5毫秒。;run方法中通过对sleep的调用表示该线程将在下面的5毫秒内处于空闲状态,5毫秒后它将再次启动运行(进入线程队列中排队)。

 

三、取得当前线程的名字和优先级

1、可通过调用Thread类的静态方法,查看当前运行的是哪一个线程。

2、获得当前线程的名字:

1currentThreadThread的静态方法,返回一个Thread的对象

    2getName

3、获得当前线程的优先级: Thread.currentThread().getPriority()setPriority();

4、判断当前正在占有CPU的那个线程:Thread.currentThread().线程的属性(与对象名比较)。

 

四、线程的属性

1、线程有四个属性

1new (新)创建状态: MyThread t = new MyThread( );或者Thread t = new MyThread();

2runnable(接口) :(可运行状态) t.start()

3blocked(被中断运行状态): sleep()wait()suspend()、其他阴塞。

4dead:死

1)自然撤消

2stop方法终止

2、新线程:当用new运算符创建一个线程时,该线程尚未运行,这意味着该线程处于“new”状态,此时程序尚未执行它里面的代码。在线程运行之前,需要进行一些程序管理操作。

3、可运行线程:一旦调用了start方法,该线程就启动成为一个可运行的线程。可运行的线程可以是尚未运行的线程。此时要由操作系统为该线程赋予运行时间。当线程内的代码开始执行时,该线程开始运行。

1)一旦线程开始运行,它不必始终保持运行状态。

2)正在运行的线程有时需要被中断,这样其他线程就有机会可以运行了。

3)线程调度的具体情况取决于操作系统提供的服务。

4)如操作系统不合作,那么java线程的实现机制要做少量的工作以便多线程能够运行。

5)在任何规定的时间上,可运行的线程可以运行,也可以不运行。

4、被中断运行的线程

1)下列操作之一,线程进入中断状态

A、调用线程的sleep方法。

B、线程调用了一个在输入、输出时中断的操作。即在输入和输出操作完成之前,该操作不会返回到它的调用程序。

C、线程调用wait方法。

D、线程试图锁定一个当前被另一个线程锁定的对象。

E、调用线程的suspend方法(此方法已作废)。

2)当一个线程被中断,可以安排另一个线程运行。

3)已中断的线程重新激活时,调度程序要查看该线程的优先级是否高于当前运行的线程。

5、退出中断状态:(与进入中断相反)

1)如线程已置于睡眠(sleep)状态,须经过规定的毫秒数

2)如线程正在进行一个输入/输出操作,须等待该操作执行完毕。

3)如线程调用了wait方法,则另一个线程必须调用notifynotifyAll

4)如线程正等待另一个线程拥有的对象锁,那么另一个线程必须放弃该锁的控制权(所有权)。

5)如线程已暂停运行(调用suspend方法),必须有人调用resume方法(已作废)。

6)如调用一个与线程上的状态不一致的方法,虚拟机会抛出一个IllegalThreadStateException异常。

6、死线程

1run方法的正常退出而自然死亡。

2)没有抓取到的异常事件终止了run方法的执行,而导致线程突然死亡。

3)特定情况下,可通过线程的stop 方法杀死线程。该方法将抛出一个ThreadDeath出错对象,从而杀死线程(已作废)。

7、判断当前线程是否存活:isAlive()

1)如是可运行或被中断,返回ture

2)如是新线程或尚未成为可运行线程,或是个死线程,返回false

 

                                        sleep←→到时间

新线程→→启动→→可运行|-----------------------------------------|被中断

                  ∣ ↑                I/O操作→完成                 ↑

                  ∣ ∣-------------------------------------------------∣

                   ∣ ↑            wait←notify/notifyAll            ↑

                  ∣ ∣-------------------------------------------------∣

                   ∣ ↑                等待锁定→锁定                 ↑

                  ∣ ∣-------------------------------------------------∣

                   ∣ ↑              挂起suspend←resume              ↑

                  ∣ ∣…………………………………………………………………∣

                   ∣                        正常退出            

                  ∣--------------------------------------------------→死

                   ∣                          stop                      ↑

                  ∣……………………………………………………………………∣

 

五、实现线程的两种方式:

1、继承Thread类。

2、实现Runnable接口。

 

六、显示定义线程

public Thread(ThreadGroup group,Runnable target,String name)

其中:第一个参数:线程组。

      第二个参数:是执行线程体(run)的目标对象,该对象必须实现Runnable接口。

      第三个参数:线程名。

 

七、启动和运行线程

1、程序启动时总是调用main方法,因此,mani方法是创建和启动线程的地方。

  MyThread t=new MyThread();  //创建

  t.start();  //运行,真正启动了一个线程。

2、构造一个新的线程,此线程从Thread类派生而来。产生对象时,并不会执行其中的run方法。

3、新线程只能由start方法启动,然后该线程才能自动执行run方法。即start()执行后自动调用run()

 

八、启动接口

1、当我们构造了线程类的一个新的实例,我们必须先告诉它在新的线程里应执行哪一段程序,我们可以在任意实现了启动接口的对象上启动一个线程。

2、启动接口是一个抽象接口,表示本对象中有一个方法想异步执行。

3Runnalbe接口中只定义了一个方法run作为线程体。

 

九、线程的优先级

1、在java语言中,每个线程都有一个优先级。

2、在默认条件下,一个线程将继承其父线程的优先级。

3、可以用setPriority方法来提高或降低线程的优先级。

4、可以设置线程的优先级:

1)最小MIX_PRIORITY1);

2)最大MAX_PRIORITY10);

3)默认NORM_PRIORITY5);

5、当线程调度程序有机会选择一个新线程时,它通常会选择当前运行的高优先级线程。

6、注意:线程优先级的使用原则是与系统有密切关系的。当虚拟机取决于主机平台的线程机制时,线程的调度完全要受线程机制的支配。虚拟机将线程优先级映射为主机平台优先级等级(主机平台的线程优先等级可能要更多或更少一些)。我们在学习过程中只是一种理想情况,每个虚拟机都可以设法在某种程度上接近这种理想的情况。

7、最高优先级的可运行线程将始终保持运行状态,直到:

1)它通过调用yield方法放弃运行为止。

2)或它不再是个可运行线程(原因是它已经死掉,或进入中断状态)。

3)或一个高优先级线程已经变成可运行线程(原因是该高优先级线程已经睡眠了足够长的时间或它的I/O操作已经完成,或有人调用了该线程正在等待的对象上的notify/notifyAll方法)。

4)此时,调用程序便选择一个新线程来运行。在可运行线程中拥有高优先级的线程将会被选中。

8、如果有多个可运行的线程,同时拥有相同的(最高)优先级,则拥有最高优先级的多个线程中的一个将被选中运行。

9、这完全取决于线程高度程序对拥有多个相同优先级的线程的仲裁。

10java语言不能保证所有线程能得到一视同仁。

11、拥有相同优先级的所有线程可能都希望依次被选中,以便使每个线程的运行都有机会取得进展。但,至少理论上讲,在某些平台上线程调度程序将会随机选择一个线程,或始终选择第一个可等到的线程。这是java语言的一个弱点,并且很难编写能够保证在所有虚拟机上以相同的方式运行多线程程序。

12、警告:有些平台(如winNT)的优先级少于java平台指定的10个级别。在这些平台上,无论选择何种优先等级的映射关系,java虚拟机的10个优先级等中的某些层次将被映射为相同的平台优先级等级。在sun 公司的LinuX java虚拟机中,线程的优先级被完全忽略。

13yield方法:用于使当前正在执行的线程放弃执行。如果有其它要运行线程的优先级至少与该线程的优先级相同时,那么它们将被安排在下次运行。注意,这是一个静态方法。

14、利己线程:当某个线程正在执行一个很长的循环时,它应该始终调用sleepyield方法,以确保它不会独占整个系统。不遵循这个原则的线程称为利己线程。

 

十、守护线程 Daemon

1、说明:

1)守护线程是一个简单的背景线程,隶属于创建它的线程,因此当创建守护线程的线程结束,守护线程也随之一起结束。

2)不是守护线程的线程叫用户线程。用户线程有它自己的生命周期,不依赖创建它的线程。当创建它的线程结束后,它可以继续执行。

3)守护线程有时也叫服务线程,它为同一个进程中的其他线程或对象提供服务,通常在一个较低的优先级上运行。如:垃圾回收线程。除此之外,它没有其他特别的功能。如果剩下的线程都是守护线程,就没有必要使程序保持运行状态,该程序便会退出运行。

    2、例:

一个网络服务器可以由一个用户线程全面管理,该用户线程启动一个或多个监听请求的守护线程。当服务器启动时,操作员启动管理线程并且由这个线程创建守护线程监听请求。守护线程将监听到的任何可以识别的请求,交由另一个由监听线程创建的线程处理,所以每个请求被独立地处理。处理事务花费有限多时间,在系统关闭前,请求被满足很重要。处理请求的线程应该是一个用户线程,以确保即使创建它的线程结束,它仍可继续运行来完成事务处理。当关闭系统时,操作员不必担心有多少线程正在运行。当主要线程关闭时,所有的监听线程也将关闭,因为它们是守护线程。然后任何处理特定事务未完成线程运行到完成。

3、使用:

1t.setDaemon(true);通过此方法可以把线程变成一个守护线程(如果为false,则为用户线程)。

2)本方法必须在线程启动运行之前调用。如在后来调用,这个方法将抛出一个IllegalThreadStateException异常。

3)由一个守护线程创建的线程默认情况也将是守护线程。

 

十一、线程组:flashget中的一个下载,同时开的线程数

1、说明

1)有些程序包含了相当数量的线程,这时按照线程的功能将它们分成不同的类别将很有用。

2)每个线程都是一个线程组的一个成员,线程组把多个线程集成一个对象,通过线程组可以同时对其中的多个线程进行操作。

3)在生成线程时,必须将线程放在指定的线程组中,也可以放在缺省的线程组中,缺省的就是生成该线程的线程所在的线程组。一旦一个线程加入某个线程组,就不能被移出这个组。

4java应用程序开始运行时,系统将生成一个名为main的线程组,但对于applet不同的浏览器会生成不同名字的线程组。

2、使用:

1)创建组

String groupName="group";

ThreadGroup g= new ThreadGroup(groupName);

2ThreadGroup构造函数的字符串参数用于标识该线程组,并且它必须是独一无二的。

3)然后,将各个线程添加到组中,方法是在构造线程时设定组。

Thread t = new Thread(g,"threadName");

4)取得现有线程的线程组:

ThreadGroup group=myThread.getTreadGroup( );

5)取得现有线程的父线程组

ThreadGroup parentGroup=group.getParent( );

6)若要确定某个线程组中的任何一个线程是否仍处于可运行状态,可使用activeCount方法。

if (g.activeCount()==0){//组中所有线程已经停止}

7)若要中断某个线程组中所有线程的运行,只需在线程组对象上调用interrupt方法:

        g.interrupt();

 

十二、同步

    1、说明:

        1)因为多线程给你提供了程序的异步执行的功能,所以在必要时必须还提供一种同步机制。

    例如,你想两个线程通讯并共享一个复杂的数据结构,你需要一种机制让他们相互牵制并

    正确执行。为这个目的,Java用一种叫监视器(monitor)的机制实现了进程间的异步执行。

    可以将监视器看作是一个很小的盒子,它只能容纳一个线程。一旦一个线程进入一个监视器

    ,所有其他线程必须等到第一个线程退出监视器后才能进入。象一把锁,每个对象和一个监视器

    对应,如果不全使用同步方法,监视器不起作用。

        2)这种监视器可以设计成保护共享的数据不被多个线程同时操作。大多数多线程系统将这种

    监视器设计成对象,Java提供了一种更清晰的解决方案。

        3)没有Monitor类:每个对象通过将他们的成员函数定义成synchronized来定义自己的监视

    器,一旦一个线程执行在一个synchronized函数里,其他任何线程都不能调用同一个对象

    synchronized函数。

2、争用条件(race condtion)大多数实际运行的多线程程序中,两个或多个线程需要共享对同一个对象的访问。如两线程访问同一对象,并且每个线程都调用一个方法,以便修改对象的状态。根据数据被访问的顺序将会产生损坏对象的情况,这种情况,通常叫作争用条件。

3、对象锁

1)当线程调用Synchronized方法时对象将转为锁定状态。

2)线程调度程序会定期使用正常的激活规则,对等待开锁的线程进行激活。

3)每当一个想要调用对象上的Synchronized(关键字)方法的线程想再次运行时,它想看该对象是否仍处于锁状态。

4)如该对象的锁已经打开,那么该线程便是下一个获得对该对象的唯一访问权限的线程。

4、等待与通知:

1wait

A、当Synehronized方法中的wait方法被调用时,当前线程将被中断运行,并且放弃该对象的锁,这可以使另一个线程启动。

BwaitObject类的方法,而不是Thread类的方法。

C、一旦线程调用了wait方法,它便进入该对象的等待列表中,被删除之前,调度程序将忽略该线程,并且该线程没有机会继续运行。

2notify/notifyAll

A、调用这两个方法,从等待列表中删除线程。

B、删除后,再次成为可运行的线程,且调度程序最终会重新激活它们。

C、然后它们试图重新进入该对象,一旦可以使用该对象锁定时,其中的一个线程将锁定该对象,且从它上次调用wait方法后的位置开始继续执行。

3)其他线程必须定期调用notify/notifyAll。这一点很重要。

4)当一个线程调用wait方法时,它不能开自己的锁,只能靠其他线程来帮它开锁。如果没有其他线程来开锁,它将永不能运行。这就产生死锁。

5、消息

     一旦你的程序被分成几个逻辑线程,你必须清晰的知道这些线程之间怎样相互通讯。java提供了waitnotify等功能来使线程之间相互交谈。一个线程可以进入某一个对象的synchronized函数进入等待状态,直到其他线程显式地将它唤醒。可以有多个线程进入同一个方法并等待同一个唤醒消息。

 

十三、小结

1、多线程是java语言的重要特点,java语言用Thread类封装了线程所有操作

2、线程的接口为Runnable

3、实现线程的两种方式

1)继承Thread

2)实现Runnable接口

4、线程之间的同步机制为Synchronized(象static一样也是关键字)

5、线程之间的通信靠wait.notify

 

常用API

1、静态方法:currentThread(),该方法返回当前正在运行的线程的对象

           yield停止当前线程

           sleep睡眠指定时间

2、实例方法

start,run,stop,suspend,resume,setPrioity,setName,getPriority,getName

3interrupt()//线程调用,消灭本线程,在线程执行完前。

4、在线程执行完run方法之前,重新执行start()方法时产生IllegalThreadStateException异常。

分享到:
评论

相关推荐

    Java多线程知识点总结

    Java多线程是Java编程语言中一个非常重要的概念,它允许开发者在一个程序中创建多个执行线程并行运行,以提高程序的执行效率和响应速度。在Java中,线程的生命周期包含五个基本状态,分别是新建状态(New)、就绪...

    java 多线程操作数据库

    ### Java多线程操作数据库:深入解析与应用 在当今高度并发的应用环境中,Java多线程技术被广泛应用于处理数据库操作,以提升系统的响应速度和处理能力。本文将基于一个具体的Java多线程操作数据库的应用程序,深入...

    Java多线程设计模式上传文件

    Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式...

    java多线程经典案例

    Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,极大地提升了程序的效率和性能。在Java中,实现多线程有两种主要方式:通过实现Runnable接口或者继承Thread类。本案例将深入探讨Java多线程中的关键...

    java多线程Demo

    Java多线程是Java编程中的一个重要概念,它允许程序同时执行多个任务,提高了程序的效率和响应速度。在Java中,实现多线程有两种主要方式:继承Thread类和实现Runnable接口。 1. 继承Thread类: 当我们创建一个新...

    java多线程的讲解和实战

    Java多线程是Java编程中的重要概念,尤其在如今的多核处理器环境下,理解并熟练掌握多线程技术对于提高程序性能和响应速度至关重要。本资料详细讲解了Java多线程的原理,并提供了丰富的实战代码,非常适合Java初学者...

    java多线程分页查询

    ### Java多线程分页查询知识点详解 #### 一、背景与需求分析 在实际的软件开发过程中,尤其是在处理大量数据时,如何高效地进行数据查询成为了一个关键问题。例如,在一个用户众多的社交平台上,当用户需要查看...

    汪文君JAVA多线程编程实战(完整不加密)

    《汪文君JAVA多线程编程实战》是一本专注于Java多线程编程的实战教程,由知名讲师汪文君倾力打造。这本书旨在帮助Java开发者深入理解和熟练掌握多线程编程技术,提升软件开发的效率和质量。在Java平台中,多线程是...

    java多线程ppt

    java多线程PPT 多线程基本概念 创建线程的方式 线程的挂起与唤醒 多线程问题

    java多线程读取文件

    Java多线程读大文件 java多线程写文件:多线程往队列中写入数据

    Java多线程机制(讲述java里面与多线程有关的函数)

    Java多线程机制是Java编程中至关重要的一部分,它允许程序同时执行多个任务,提升应用程序的效率和响应性。以下是对各个知识点的详细说明: 9.1 Java中的线程: Java程序中的线程是在操作系统级别的线程基础上进行...

    深入浅出 Java 多线程.pdf

    在本文中,我们将深入浅出Java多线程编程的世界,探索多线程编程的基本概念、多线程编程的优点、多线程编程的缺点、多线程编程的应用场景、多线程编程的实现方法等内容。 一、多线程编程的基本概念 多线程编程是指...

    java 多线程并发实例

    在Java编程中,多线程并发是提升程序执行效率、充分利用多核处理器资源的重要手段。本文将基于"java 多线程并发实例"这个主题,深入探讨Java中的多线程并发概念及其应用。 首先,我们要了解Java中的线程。线程是...

    JAVAJAVA多线程教学演示系统论文

    《JAVA多线程教学演示系统》是一篇深入探讨JAVA多线程编程的论文,它针对教育领域中的教学需求,提供了一种生动、直观的演示方式,帮助学生更好地理解和掌握多线程技术。这篇论文的核心内容可能包括以下几个方面: ...

    java多线程实现大批量数据导入源码

    本项目以"java多线程实现大批量数据导入源码"为题,旨在通过多线程策略将大量数据切分,并进行并行处理,以提高数据处理速度。 首先,我们需要理解Java中的线程机制。Java通过`Thread`类来创建和管理线程。每个线程...

    java多线程查询数据库

    综上所述,"java多线程查询数据库"是一个涉及多线程技术、线程池管理、并发控制、分页查询等多个方面的复杂问题。通过理解和掌握这些知识点,我们可以有效地提高数据库操作的效率和系统的响应速度。

    java 多线程编程实战指南(核心 + 设计模式 完整版)

    《Java多线程编程实战指南》这本书深入浅出地讲解了Java多线程的核心概念和实战技巧,分为核心篇和设计模式篇,旨在帮助开发者掌握并应用多线程技术。 1. **线程基础** - **线程的创建**:Java提供了两种创建线程...

    JAVA多线程编程技术PDF

    这份“JAVA多线程编程技术PDF”是学习和掌握这一领域的经典资料,涵盖了多线程的全部知识点。 首先,多线程的核心概念包括线程的创建与启动。在Java中,可以通过实现Runnable接口或继承Thread类来创建线程。创建后...

    Java多线程编程核心技术_完整版_java_

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,多线程主要通过继承Thread类或实现Runnable接口来实现。本教程《Java多线程编程核心技术》将...

    Java多线程编程实战指南(核心篇)

    Java多线程编程实战指南(核心篇) 高清pdf带目录 随着现代处理器的生产工艺从提升处理器主频频率转向多核化,即在一块芯片上集成多个处理器内核(Core),多核处理器(Multicore Processor)离我们越来越近了――如今...

Global site tag (gtag.js) - Google Analytics