`
endual
  • 浏览: 3558494 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Java多线程总结

    博客分类:
  • java
 
阅读更多

<!-- [if !mso]> <style> v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style> <![endif]--><!-- [if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning/> <w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing> <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery> <w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:SpaceForUL/> <w:BalanceSingleByteDoubleByteWidth/> <w:DoNotLeaveBackslashAlone/> <w:ULTrailSpace/> <w:DoNotExpandShiftReturn/> <w:AdjustLineHeightInTable/> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:UseFELayout/> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!-- [if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--><!-- [if !mso]> <object classid="clsid:38481807-CA0E-42D2-BF39-B33AF135CC4D" id=ieooui> </object> <style> st1\:*{behavior:url(#ieooui) } </style> <![endif]--><!-- [if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} </style> <![endif]-->

Java 多线程总结

 

线程的四种状态:

 

就绪Runable ——运行中Running ——阻塞Blocked ——死亡Dead( 结束)

 

  线程的状态转换图

 

线程在一定条件下,状态会发生变化。线程变化的状态转换图如下:

1 、新建状态(New ):新创建了一个线程对象。

2 、就绪状态(Runnable ):线程对象创建后,其他线程调用了该对象的start() 方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU 的使用权。

3 、运行状态(Running ):就绪状态的线程获取了CPU ,执行程序代码。

4 、阻塞状态(Blocked ):阻塞状态是线程因为某种原因放弃CPU 使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:

(一)、等待阻塞:运行的线程执行wait() 方法,JVM 会把该线程放入等待池中。

(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM 会把该线程放入锁池中。

(三)、其他阻塞:运行的线程执行sleep()join() 方法,或者发出了I/O 请求时,JVM 会把该线程置为阻塞状态。当sleep() 状态超时、join() 等待线程终止或者超时、或者I/O 处理完毕时,线程重新转入就绪状态。

5 、死亡状态(Dead ):线程执行完了或者因异常退出了run() 方法,该线程结束生命周期。

线程的调度

1 、调整线程优先级:Java 线程有优先级,优先级高的线程会获得较多的运行机会。

 Java 线程的优先级用整数表示,取值范围是1~10Thread 类有以下三个静态常量:

static int MAX_PRIORITY           线程可以具有的最高优先级,取值为10

static int MIN_PRIORITY           线程可以具有的最低优先级,取值为1

static int NORM_PRIORITY           分配给线程的默认优先级,取值为5

 Thread 类的setPriority()getPriority() 方法分别用来设置和获取线程的优先级。

  每个线程都有默认的优先级。主线程的默认优先级为Thread.NORM_PRIORITY

线程的优先级有继承关系,比如A 线程中创建了B 线程,那么B 将和A 具有相同的优先级。

JVM 提供了10 个线程优先级,但与常见的操作系统都不能很好的映射。如果希望程序能移植到各个操作系统中,应该仅仅使用Thread 类有以下三个静态常量作为优先级,这样能保证同样的优先级采用了同样的调度方式。

 2 、线程睡眠:Thread.sleep(long millis) 方法,使线程转到阻塞状态。millis 参数设定睡眠的时间,以毫秒为单位。当睡眠结束后,就转为就绪(Runnable )状态。

 3 、线程等待:Object 类中的wait() 方法,导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 唤醒方法。这个两个唤醒方法也是Object 类中的方法,行为等价于调用 wait(0) 一样。

 4 、线程让步:Thread.yield() 方法,暂停当前正在执行的线程对象,把执行机会让给相同或者更高优先级的线程。

 5 、线程加入:join() 方法,等待其他线程终止。在当前线程中调用另一个线程的join() 方法,则当前线程转入阻塞状态,直到另一个线程运行结束,当前线程再由阻塞转为就绪状态。

 6 、线程唤醒:Object 类中的notify() 方法,唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。 直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争;例如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。类似的方法还有一个notifyAll() ,唤醒在此对象监视器上等待的所有线程。

 

JAVA 多线程实现的两种模型

 

区别与联系:

l         Runnable Thread 的接口,在大多数情况下 推荐用接口的方式 生成线程,因为接口可以实现多继承,况且 Runnable 只有一个 run 方法,很适合继承。

l         在使用 Thread 的时候只需要 new 一个实例出来,调用 start() 方法即可以启动一个线程。 Thread Test = new Thread();
Test.start();

l         在使用 Runnable 的时候需要先 new 一个实现 Runnable 的类的实例,之后,创建线程时将线程与该实例关联(其本质是让该线程执行时调用该实例中的 run 方法 )。

 

 

l         扩展Thread 类实现

class MyThread extends Thread {

    public MyThread (String threadName) {

        super(threadName);

    }

    public void run() {

        System.out.println(getName() + " 线程运行开始!");

        for (int i = 0; i < 10; i++) {

            System.out.println(i + " " + getName());

            try {

                sleep((int) Math.random() * 10);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

        }

        System.out.println(getName() + " 线程运行结束!");

    }

}

 

public class TestMyThread {

    public static void main(String[] rags) {

        System.out.println(Thread.currentThread().getName() + " 线程运行开始!");

        new MyThread ("A").start();

        new MyThread ("B").start();

        System.out.println(Thread.currentThread().getName() + " 线程运行结束!");

    }

}

运行结果:

main 线程运行开始!

main 线程运行结束!

A 线程运行开始!

0 A

1 A

B 线程运行开始!

2 A

0 B

3 A

4 A

1 B

5 A

6 A

7 A

8 A

9 A

A 线程运行结束!

2 B

3 B

4 B

5 B

6 B

7 B

8 B

9 B

B 线程运行结束!

  说明:

程序启动运行main 时候,java 虚拟机启动一个进程,主线程mainmain() 调用时候被创建。随着调用MyThread 的两个对象的start 方法,另外两个线程也启动了,这样,整个应用就在多线程下运行。

  在一个方法中调用Thread.currentThread().getName() 方法,可以获取当前线程的名字。在mian 方法中调用该方法,获取的是主线程的名字。

  注意:start() 方法的调用后并不是立即执行多线程代码,而是使得该线程变为可运行态(Runnable ),什么时候运行是由操作系统决定的。从程序运行的结果可以发现,多线程程序是乱序执行。因此,只有乱序执行的代码才有必要设计为多线程。

Thread.sleep() 方法调用目的是不让当前线程独自霸占该进程所获取的CPU 资源,以留出一定时间给其他线程执行的机会。实际上所有的多线程代码执行顺序都是不确定的,每次执行的结果都是随机的。

l         实现java.lang.Runnable 接口

public class TestMyThread implements Runnable {

     public static void main(String[] args) {

        System.out.println(Thread.currentThread().getName() + " 线程运行开始!");

       TestMyThread test = new TestMyThread ();

        Thread thread1 = new Thread(test);

        Thread thread2 = new Thread(test);

        thread1.start();

        thread2.start();

        System.out.println(Thread.currentThread().getName() + " 线程运行结束!");

    }

     public void run() {

        System.out.println(Thread.currentThread().getName() + " 线程运行开始!");

        for (int i = 0; i < 10; i++) {

            System.out.println(i + " " + Thread.currentThread().getName());

            try {

                Thread.sleep((int) Math.random() * 10);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

        }

        System.out.println(Thread.currentThread().getName() + " 线程运行结束!");

    }

}

  运行结果:

main 线程运行开始!

Thread-0 线程运行开始!

main 线程运行结束!

0 Thread-0

Thread-1 线程运行开始!

0 Thread-1

1 Thread-1

1 Thread-0

2 Thread-0

2 Thread-1

3 Thread-0

3 Thread-1

4 Thread-0

4 Thread-1

5 Thread-0

6 Thread-0

5 Thread-1

7 Thread-0

8 Thread-0

6 Thread-1

9 Thread-0

7 Thread-1

Thread-0 线程运行结束!

8 Thread-1

9 Thread-1

Thread-1 线程运行结束!

  说明:

TestMitiThread1 类通过实现Runnable 接口,使得该类有了多线程类的特征。run ()方法是多线程程序的一个约定。所有的多线程代码都在run 方法里面。Thread 类实际上也是实现了Runnable 接口的类。

在启动的多线程的时候,需要先通过Thread 类的构造方法Thread(Runnable target) 构造出对象,然后调用Thread 对象的start() 方法来运行多线程代码。

 

实际上所有的多线程代码都是通过运行Threadstart() 方法来运行的。因此,不管是扩展Thread 类还是实现Runnable 接口来实现多线程,最终还是通过Thread 的对象的API 来控制线程的,熟悉Thread 类的API 是进行多线程编程的基础。

 

读解ThreadAPI

构造方法摘要

Thread(Runnable target)              分配新的 Thread 对象。

Thread(String name)                  分配新的 Thread 对象。

  方法摘要

static Thread currentThread()          

说明:返回对当前正在执行的线程对象的引用。

void start()

说明:使该线程开始执行;Java 虚拟机调用该线程的 run 方法。

void stop()

说明:已过时, 该方法具有固有的不安全性。

void suspend()

说明:已过时。 该方法已经遭到反对,因为它具有固有的死锁倾向。

void resume()          

说明:该方法已过时,它只与 suspend() 一起使用,但 suspend() 已经遭到反对,因为它具有死锁倾向。

static void sleep(long millis)

说明:在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)。

static void sleep(long millis, int nanos)

说明:在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行)。

static void yield()

说明:线程让权,暂停当前正在执行的线程对象,并执行其他线程。

void interrupt()        说明:中断线程。

void join()           

说明:等待其他线程终止。在当前线程中调用另一个线程的join() 方法,则当前线程转入阻塞状态,直到另一个线程运行结束,当前线程再由阻塞转为就绪状态。

void run()        说明:线程方法运行。

String toString()

说明:返回该线程的字符串表示形式,包括线程名称、优先级和线程组。

分享到:
评论

相关推荐

    JAVA多线程总结

    【JAVA多线程总结】 Java 多线程是Java编程中的关键特性,它允许程序同时执行多个任务,提高系统的效率和响应性。本篇总结涵盖了Java多线程的基础概念、创建与启动、线程调度、同步与协作以及新特性。 **一、Java...

    java多线程总结(一)

    Java多线程是Java编程语言中的一个重要特性,它允许开发者创建并发执行的多个线程,从而提高程序的执行效率和响应速度。Java中实现多线程主要有两种方式:继承Thread类和实现Runnable接口。 ### 继承Thread类 在...

    java多线程总结

    Java多线程是Java编程中的核心概念,它允许程序同时执行多个任务,提高了程序的效率和响应速度。本文将深入探讨Java多线程的相关知识点,包括线程的创建、线程的状态、同步机制以及线程安全问题。 1. **线程的创建*...

    Java并发编程实践(java concurrency in practice)pdf (java多线程总结.ppt)

    配合`JAVA多线程总结.ppt`,你可以得到一个更直观和简洁的概览,快速回顾和掌握上述关键知识点。虽然中文版翻译可能存在不足,但原版英文书籍通常能更准确地传达作者的意图和细节,值得深入阅读。

    Java多线程知识点总结

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

    Java多线程总结.pdf

    Java多线程是指在Java语言中同时运行多个线程,从而实现对任务的并行处理。这是Java中一个非常重要的概念和技能,尤其在需要高并发处理和优化性能的场景中显得尤为重要。以下将详细梳理Java多线程编程中的一些关键...

    java多线程总结(二)

    Java多线程是Java编程语言中的一个重要特性,它允许在单个程序中同时执行多个代码路径,从而提高程序的效率和响应性。在Java中,线程生命周期包括六种状态:新建状态(NEW)、可运行状态(RUNNABLE)、休眠状态...

    Java多线程的总结

    Java多线程是Java编程中的一个核心概念,它在现代软件开发中扮演着至关重要的角色。多线程允许程序同时执行多个任务,提高了系统资源的利用率,提升了应用程序的响应速度和并发性能。对于大型分布式系统、Web应用...

    JAVA深化篇-34- 全网最全JAVA多线程总结思维【不看保准后悔,可供下载】

    java多线程思维导图总结【超详细,可下载】

    Java多线程编程总结

    ### Java多线程编程总结 #### 一、Java线程:概念与原理 1. **操作系统中线程和进程的概念** - 当前的操作系统通常为多任务操作系统,多线程是实现多任务的一种手段。 - **进程**:指内存中运行的应用程序,每个...

    java多线程编程总结

    ### Java多线程编程总结 #### 一、Java线程:概念与原理 - **操作系统中线程和进程的概念** 当前的操作系统通常都是多任务操作系统,多线程是一种实现多任务的方式之一。在操作系统层面,进程指的是内存中运行的...

    java多线程分页查询

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

    java多线程全面总结

    java多线程全面总结,简单的介绍多线程技术中的各种应用问题,是你对多线程有更多的认识!

    JAVA多线程的总结

    JAVA 多线程总结 扩展java lang Thread类 实现java lang Runnable接口

    JAVA多线程编程技术PDF

    总结起来,“JAVA多线程编程技术PDF”涵盖了多线程的基本概念、同步机制、线程通信、死锁避免、线程池以及线程安全的集合类等内容。通过深入学习这份资料,开发者可以全面掌握Java多线程编程技术,提升程序的并发...

    JAVA多线程(精典总结)

    总结一下,Java多线程涉及的内容广泛,包括线程的基本概念、创建、状态转换、调度和优先级管理。理解并掌握这些知识点对于编写高效并发的Java程序至关重要,也是面试中必不可少的技术点。在实际编程中,合理利用多...

    武汉理工大学Java多线程实验源码

    总结来说,这个实验源码涵盖了Java多线程的基础和应用,包括线程的创建、运行、同步、通信,以及网络编程和数据库操作。通过这些实验,学生可以深入理解Java并发编程的核心概念,并掌握实际开发中的多线程设计技巧。

    我总结的Java多线程程序设计

    Java多线程程序设计是Java开发中的重要组成部分,它允许程序在同一时间执行多个任务,从而提高了系统的效率和响应性。本文将深入探讨Java多线程的相关概念和实现方式。 一、理解多线程 1. **线程定义**:线程是一...

Global site tag (gtag.js) - Google Analytics