`
coolerbaosi
  • 浏览: 729070 次
文章分类
社区版块
存档分类
最新评论

java多线程小结

 
阅读更多
学习了一下JAVA多线程方面的知识,在此总结一下

1、在Java程序中,JVM负责线程的调度。线程调度是指按照特定的机制为多个线程分配CPU的使用权。 调度的模式有两种:分时调度和抢占式调度。分时调度是所有线程轮流获得CPU使用权,并平均分配每个线程占用CPU的时间;抢占式调度是根据线程的优先级别来获取CPU的使用权。JVM的线程调度模式采用了抢占式模式。

2、Thread类实际上也是实现了Runnable接口的类。 在启动的多线程的时候,需要先通过Thread类的构造方法Thread(Runnable target) 构造出对象,然后调用Thread对象的start()方法来运行多线程代码。 实际上所有的多线程代码都是通过运行Thread的start()方法来运行的。因此,不管是扩展Thread类还是实现Runnable接口来实现多线程,最终还是通过Thread的对象的API来控制线程的,熟悉Thread类的API是进行多线程编程的基础。

3、JAVA多线程涉及到2个问题,一个是线程的调度,另一个是线程的同步

4、线程的状态有:new、runnable、running、waiting、timed_waiting、blocked、dead 当执行new Thread(Runnable r)后,新创建出来的线程处于new状态,这种线程不可能执行 当执行thread.start()后,线程处于runnable状态,这种情况下只要得到CPU,就可以开始执行了。runnable状态的线程,会接受JVM的调度,进入running状态,但是具体何时会进入这个状态,是随机不可知的 running状态中的线程最为复杂,可能会进入runnable、waiting、timed_waiting、blocked、dead状态: 如果CPU调度给了别的线程,或者执行了Thread.yield()方法,则进入runnable状态,但是也有可能立刻又进入running状态 如果执行了Thread.sleep(long),或者thread.join(long),或者在锁对象上调用object.wait(long)方法,则会进入timed_waiting状态 如果执行了thread.join(),或者在锁对象上调用了object.wait()方法,则会进入waiting状态 如果进入了同步方法或者同步代码块,没有获取锁对象的话,则会进入blocked状态 处于waiting状态中的线程,如果是因为thread.join()方法进入等待的话,在目标thread执行完毕之后,会回到runnable状态;如果是因为object.wait()方法进入等待的话,在锁对象执行object.notify()或者object.notifyAll()之后会回到runnable状态 处于timed_waiting状态中的线程,和waiting状态中的差不多,只不过是设定时间到了,就会回到runnable状态 处于blocked状态中的线程,只有获取了锁之后,才会脱离阻塞状态 当线程执行完毕,或者抛出了未捕获的异常之后,会进入dead状态,该线程结束

5、当线程池中线程都具有相同的优先级,调度程序的JVM实现自由选择它喜欢的线程。这时候调度程序的操作有两种可能:一是选择一个线程运行,直到它阻塞或者运行完成为止。二是时间分片,为池内的每个线程提供均等的运行机会。

6、设置线程的优先级:线程默认的优先级是创建它的执行线程的优先级。可以更改线程的优先级。 JVM从不会改变一个线程的优先级。然而,1-10之间的值是没有保证的。一些JVM可能不能识别10个不同的值,而将这些优先级进行每两个或多个合并,变成少于10个的优先级,则两个或多个优先级的线程可能被映射为一个优先级。

7、Thread.yield()方法作用是:暂停当前正在执行的线程对象,并执行其他线程。 yield()应该做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。 结论:yield()从未导致线程转到等待/睡眠/阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。

8、另一个问题是线程的同步,这个我感觉比调度更加复杂一些 Java中每个对象都有一个“内置锁”,也有一个内置的“线程表” 当程序运行到非静态的synchronized方法上时,会获得与正在执行代码类的当前实例(this实例)有关的锁;当运行到同步代码块时,获得与声明的对象有关的锁 释放锁是指持锁线程退出了synchronized方法或代码块。 当程序运行到synchronized同步方法或代码块时对象锁才起作用。 一个对象只有一个锁。所以,如果一个线程获得该锁,就没有其他线程可以获得锁,直到第一个线程释放(或返回)锁。这也意味着任何其他线程都不能进入该对象上的synchronized方法或代码块,直到该锁被释放。

9、当提到同步(锁定)时,应该清楚是在哪个对象上同步(锁定)?

10、 obj.wait() obj.notify() obj.notifyAll() 关于这3个方法,有一个关键问题是: 必须从同步环境内调用wait()、notify()、notifyAll()方法。只有拥有该对象的锁的线程,才能调用该对象上的wait()、notify()、notifyAll()方法 与每个对象具有锁一样,每个对象也可以有一个线程列表,他们等待来自该对象的通知。线程通过执行对象上的wait()方法获得这个等待列表。从那时候起,它不再执行任何其他指令,直到调用对象的notify()方法为止。如果多个线程在同一个对象上等待,则将只选择一个线程(不保证以何种顺序)继续执行。如果没有线程等待,则不采取任何特殊操作。

11、下面贴几个代码实例,配合jstack命令说明一下 jstack输出的结果是: "main" prio=6 tid=0x00846800 nid=0x1638 waiting on condition [0x0092f000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at net.kyfxbl.lock.ThreadA.main(ThreadA.java:20) - locked <0x22a18a90> (a net.kyfxbl.lock.ThreadB) "Thread-0" prio=6 tid=0x02bbb800 nid=0x1410 waiting for monitor entry [0x02f0f000] java.lang.Thread.State: BLOCKED (on object monitor) at net.kyfxbl.lock.ThreadB.run(ThreadB.java:11) - waiting to lock <0x22a18a90> (a net.kyfxbl.lock.ThreadB) 可以看到,主线程和新线程在同一个对象上锁定,主线程的方法里执行了Thread.sleep(60000),因此进入了TIMED_WAITING状态,而新线程则进入BLOCKED状态 jstack输出的结果是: "main" prio=6 tid=0x00846800 nid=0x1684 in Object.wait() [0x0092f000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x22a18b08> (a net.kyfxbl.lock.ThreadB) at java.lang.Object.wait(Object.java:485) at net.kyfxbl.lock.ThreadA.main(ThreadA.java:22) - locked <0x22a18b08> (a net.kyfxbl.lock.ThreadB) "Thread-0" prio=6 tid=0x02bcc800 nid=0x19c waiting on condition [0x02f0f000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at net.kyfxbl.lock.ThreadB.run(ThreadB.java:12) - locked <0x22a18b08> (a net.kyfxbl.lock.ThreadB) 2个线程还是在同一个对象上同步,但这次主线程立刻执行了b.wait()方法,因此释放了对象b上的锁,自己进入了WAITING状态。接下来新线程得到了对象b上的锁,所以没有进入阻塞状态,紧接着执行Thread.sleep(60000)方法,进入了TIMED_WAITING状态 jstack输出的结果是: "main" prio=6 tid=0x00846800 nid=0x3ec in Object.wait() [0x0092f000] java.lang.Thread.State: BLOCKED (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x22a18ba0> (a net.kyfxbl.lock.ThreadB) at java.lang.Object.wait(Object.java:485) at net.kyfxbl.lock.ThreadA.main(ThreadA.java:20) - locked <0x22a18ba0> (a net.kyfxbl.lock.ThreadB) "Thread-0" prio=6 tid=0x02bbb800 nid=0x14b4 waiting on condition [0x02f0f000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at net.kyfxbl.lock.ThreadB.run(ThreadB.java:19) - locked <0x22a18ba0> (a net.kyfxbl.lock.ThreadB) 当主线程执行b.wait()之后,就进入了WAITING状态,但是新线程执行notifyAll()之后,有一个瞬间主线程回到了RUNNABLE状态,但是好景不长,由于这个时候新线程还没有释放锁,所以主线程立刻进入了BLOCKED状态

12、当在对象上调用wait()方法时,执行该代码的线程立即放弃它在对象上的锁。然而调用notify()时,并不意味着这时线程会放弃其锁。如果线程仍然在完成同步代码,则线程在移出之前不会放弃锁。因此,只要调用notify()并不意味着这时该锁被释放

13、与线程休眠类似,线程的优先级仍然无法保障线程的执行次序。只不过,优先级高的线程获取CPU资源的概率较大,优先级低的并非没机会执行。

14、在一个线程中开启另外一个新线程,则新开线程称为该线程的子线程,子线程初始优先级与父线程相同。

15、JRE判断程序是否执行结束的标准是所有的前台执线程行完毕了,而不管后台线程的状态,因此,在使用后台线程时候一定要注意这个问题。

16、下面说说我们这次JBOSS挂死问题的处理方法 现象:系统运行一段时间之后,发现有几个子系统无法访问了,但是另外几个可以。CPU占用达到100% 观察了一下,发现无法访问的应用都部署在同一个JBOSS里,于是把该JBOSS的堆栈用jstack命令输出 发现里面有大量的线程处于BLOCKED状态,均是在执行到c3p0的一个方法里的某一行时,BLOCKED住了 于是下载c3p0的源码,跟进去看了一下,这是一个同步方法,内部会去获取数据库连接,如果获取到连接,就进行下一步操作,如果获取不到,就执行sleep(long timeout)方法。 反推一下,我猜测可能是这样的: 由于某段代码没有释放数据库连接-->连接池中的连接耗尽-->部分线程无限TIMED_WAITING-->其余线程都BLOCKED-->开启新线程-->频繁引发GC-->占用大量CPU-->应用挂起 后来对所有涉及到数据库连接的代码进行排查,发现确实有几个地方做完数据库操作以后,没有释放连接。把这部分代码改掉,重新启动JBOSS,没有再出现JBOSS挂起的现象

分享到:
评论

相关推荐

    Java多线程小结

    Java中多线程的学习的自我小结,有多线程的意思,多线程常见的控制方法等内容

    JAVA多线程操作方法实用大全

    欧柏泰克教学小结:JAVA多线程操作方法实用大全

    java线程详解

    八、线程同步小结 Java线程:线程的交互 Java线程:线程的调度-休眠 Java线程:volatile关键字 Java线程:新特征-线程池 一、固定大小的线程池 二、单任务线程池 三、可变尺寸的线程池 四、延迟连接池 五、...

    分享40个Java多线程问题小结

    多个线程共存于同一JVM进程里面,所以共用相同的内存空间,较之多进程,多线程之间的通信更轻量级,本文给大家分享40个Java多线程问题小结 的相关资料,需要的朋友可以参考下

    JAVA实现线程的方法

    欧柏泰克课堂小结:JAVA实现线程的方法

    Java程序设计案例教程-第8章-多线程编程.pptx

    第4页 主要内容 8.1 Java线程模型 8.2 创建线程 8.3 同步与线程间通信 8.4 获取线程状态 8.5 本章小结 8.6 思考和练习 Java程序设计案例教程-第8章-多线程编程全文共36页,当前为第4页。 8.1 Java线程模型 Java对多...

    Java线程安全问题小结_动力节点Java学院整理

    主要介绍了Java线程安全问题小结的相关资料,需要的朋友可以参考下

    JAVA清华大学教程

    ◇6.2 多线程的互斥与同步 ◇6.3 Java Applet ◇本讲小结 ◇课后习题 ★ 第七讲 Swing用户界面设计 ◇课前索引 ◇7.1 Swing简介 ◇7.2 Swing组件和容器 ◇本讲小结 ◇课后习题 ★ 第八讲 Java网络编程 ◇...

    实验5 JAVA常用类.doc

    本专栏主要为Java程序设计(基础)实验报告和Java程序设计(进阶)...进阶篇有反射、泛型、注解、网络编程、多线程、序列化、数据库、Servlet、JSP、XML解析、单例模式与枚举。本专栏主要为Java入门者提供实验参考。

    突破JAVA万人面试,懂多线程者得天下.zip

    目录网盘文件永久链接 01课程安排av 02什么是并发和并行av ...08线程创建小结av 09线程生命周期avi 10.线程安全问题什么是线程安全avi 11线程安全同题问题分析avi 12线程安全问题线程安全问题演示avi ...............

    JAVA 清华大学 教程

    ◇6.2 多线程的互斥与同步 ◇6.3 Java Applet ◇本讲小结 ◇课后习题 ★ 第七讲 Swing用户界面设计 ◇课前索引 ◇7.1 Swing简介 ◇7.2 Swing组件和容器 ◇本讲小结 ◇课后习题 ★ 第八讲 Java网络编程 ◇...

    清华大学JAVA教程

    ◇6.2 多线程的互斥与同步 ◇6.3 Java Applet ◇本讲小结 ◇课后习题 ★ 第七讲 Swing用户界面设计 ◇课前索引 ◇7.1 Swing简介 ◇7.2 Swing组件和容器 ◇本讲小结 ◇课后习题 ★ 第八讲 Java网络编程 ◇...

    Java编程语言详细教程

    ◇6.2 多线程的互斥与同步 ◇6.3 Java Applet ◇本讲小结 ◇课后习题 ★ 第七讲 Swing用户界面设计 ◇课前索引 ◇7.1 Swing简介 ◇7.2 Swing组件和容器 ◇本讲小结 ◇课后习题 ★ 第八讲 Java网络编程 ◇...

    (超赞)JAVA精华之--深入JAVA API

    1.7 Java 5.0多线程编程 1.8 Java Socket编程 1.9 Java的内存泄漏 1.10 抽象类与接口的区别 1.11 Java变量类型间的相互转换 2 JAVA与WEB 2.1 JMX规范 2.1.1 JMX概述 2.1.2 设备层(Instrumentation Level) 2.1.3 ...

    Java基础知识点总结.docx

    Java数组与集合小结 305 递归 309 对象的序列化 310 Java两种线程类:Thread和Runnable 315 Java锁小结 321 java.util.concurrent.locks包下常用的类 326 NIO(New IO) 327 volatile详解 337 Java 8新特性 347 Java...

    Java优化编程(第2版)

    第12章 java多线程技术与应用性能优化 12.1 java多线程技术 12.1.1 进程与线程 12.1.2 线程的生命周期 12.2 并行任务与性能 12.2.1 并行任务与多线程 12.2.2 并行任务与死锁 12.3 线程池技术与应用性能优化 12.3.1 ...

    Java语言程序设计实验指导书

    Java语言程序设计实验指导书 前 言  Java语言是计算机专业的一门重要的专业,是在实际开发中的一个非常重要开发工具。Java语言由于其平台无关性和自己就是一个网络编程语言,使得它在...实验6:Java中的多线程 12

    Java测试新技术TestNG和高级概念.part1

    2.5 测试多线程代码 2.6 性能测试 2.7 模拟和桩 2.8 依赖的测试 2.9 继承和annotation范围 2.10 测试分组 2.11 代码覆盖率 2.12 本章小结 第3章 企业级测试 3.1 典型企业级场景 3.2 一个具体例子 3.3 测试实现 ...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    7.11 小结:多方位理解Java方法 191 7.12 习题 192 第8章 Java中的包(Package)命名习惯和注释 193 教学视频:43分钟 8.1 Java中的包(Package) 193 8.1.1 Java中的包 193 8.1.2 在Eclipse中使用包 194 ...

Global site tag (gtag.js) - Google Analytics