`
mario_design
  • 浏览: 31054 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

浅析Java多线程编程中的高级技术

    博客分类:
  • java
阅读更多
线程组

线程是被个别创建的,但可以将它们归类到线程组中,以便于调试和监视。只能在创建线程的同时将它与一个线程组相关联。在使用大量线程的程序中,使用线程组组织线程可能很有帮助。可以将它们看作是计算机上的目录和文件结构。

  线程间发信

当线程在继续执行前需要等待一个条件时,仅有 synchronized 关键字是不够的。虽然 synchronized 关键字阻止并发更新一个对象,但它没有实现线程间发信。Object 类为此提供了三个函数:wait()、notify() 和 notifyAll()。以全球气候预测程序为例。这些程序通过将地球分为许多单元,在每个循环中,每个单元的计算都是隔离进行的,直到这些值趋于稳定, 然后相邻单元之间就会交换一些数据。所以,从本质上讲,在每个循环中各个线程都必须等待所有线程完成各自的任务以后才能进入下一个循环。这个模型称为 屏蔽同步,下例说明了这个模型:

 屏蔽同步

public class BSync {
int totalThreads;
int currentThreads;

public BSync(int x) {
totalThreads = x;
currentThreads = 0;
}

public synchronized void waitForAll() {
currentThreads++;
if(currentThreads < totalThreads) {
try {
wait();
} catch (Exception e) {}
}
else {
currentThreads = 0;
notifyAll();
}
}
}

   当对一个线程调用 wait() 时,该线程就被有效阻塞,只到另一个线程对同一个对象调用 notify() 或 notifyAll() 为止。因此,在前一个示例中,不同的线程在完成它们的工作以后将调用 waitForAll() 函数,最后一个线程将触发 notifyAll() 函数,该函数将释放所有的线程。第三个函数 notify() 只通知一个正在等待的线程,当对每次只能由一个线程使用的资源进行访问限制时,这个函数很有用。但是,不可能预知哪个线程会获得这个通知,因为这取决于 Java 虚拟机 (JVM) 调度算法。

将 CPU 让给另一个线程

当线程放弃某个稀有的资源(如数据库连接或网络端口)时,它可能调用 yield() 函数临时降低自己的优先级,以便某个其他线程能够运行。

  守护线程

有两类线程:用户线程和守护线程。用户线程是那些完成有用工作的线程。 守护线程是那些仅提供辅助功能的线程。Thread 类提供了 setDaemon() 函数。Java 程序将运行到所有用户线程终止,然后它将破坏所有的守护线程。在 Java 虚拟机 (JVM) 中,即使在 main 结束以后,如果另一个用户线程仍在运行,则程序仍然可以继续运行。

 避免不提倡使用的方法

不提倡使用的方法是为支持向后兼容性而保留的那些方法,它们在以后的版本中可能出现,也可能不出现。Java 多线程支持在版本 1.1 和版本 1.2 中做了重大修订,stop()、suspend() 和 resume() 函数已不提倡使用。这些函数在 JVM 中可能引入微妙的错误。虽然函数名可能听起来很诱人,但请抵制诱惑不要使用它们。

调试线程化的程序

在线程化的程序中,可能发生的某些常见而讨厌的情况是死锁、活锁、内存损坏和资源耗尽。

  死锁

死锁可能是多线程程序最常见的问题。当一个线程需要一个资源而另一个线程持有该资源的锁时,就会发生死锁。这种情况通常很难检测。但是,解决方案却相当 好:在所有的线程中按相同的次序获取所有资源锁。例如,如果有四个资源 ?A、B、C 和 D ? 并且一个线程可能要获取四个资源中任何一个资源的锁,则请确保在获取对 B 的锁之前首先获取对 A 的锁,依此类推。如果“线程 1”希望获取对 B 和 C 的锁,而“线程 2”获取了 A、C 和 D 的锁,则这一技术可能导致阻塞,但它永远不会在这四个锁上造成死锁。

  活锁

当一个线程忙于接受新任务以致它永远没有机会完成任何任务时,就会发生活锁。这个线程最终将超出缓冲区并导致程序崩溃。试想一个秘书需要录入一封信,但她一直在忙于接电话,所以这封信永远不会被录入。 内存损坏

如果明智地使用 synchronized 关键字,则完全可以避免内存错误这种气死人的问题。

 资源耗尽

某些系统资源是有限的,如文件描述符。多线程程序可能耗尽资源,因为每个线程都可能希望有一个这样的资源。如果线程数相当大,或者某个资源的侯选线程数 远远超过了可用的资源数,则最好使用 资源池。一个最好的示例是数据库连接池。只要线程需要使用一个数据库连接,它就从池中取出一个,使用以后再将它返回池中。资源池也称为 资源库。

调试大量的线程

有时一个程序因为有大量的线程在运行而极难调试。在这种情况下,下面的这个类可能会派上用场:

public class Probe extends Thread {
public Probe() {}
public void run() {
while(true) {
Thread[] x = new Thread[100];
Thread.enumerate(x);
for(int i=0; i<100; i++) {
Thread t = x[i];
if(t == null)
break;
else
System.out.println(t.getName() + "\t" + t.getPriority()+ "\t" + t.isAlive() + "\t" + t.isDaemon());
}
}
}
}

  限制线程优先级和调度

Java 线程模型涉及可以动态更改的线程优先级。本质上,线程的优先级是从 1 到 10 之间的一个数字,数字越大表明任务越紧急。JVM 标准首先调用优先级较高的线程,然后才调用优先级较低的线程。但是,该标准对具有相同优先级的线程的处理是随机的。如何处理这些线程取决于基层的操作系统 策略。在某些情况下,优先级相同的线程分时运行;在另一些情况下,线程将一直运行到结束。请记住,Java 支持 10 个优先级,基层操作系统支持的优先级可能要少得多,这样会造成一些混乱。因此,只能将优先级作为一种很粗略的工具使用。最后的控制可以通过明智地使用 yield() 函数来完成。通常情况下,请不要依靠线程优先级来控制线程的状态。

  小结

本文说明了在 Java 程序中如何使用线程。像是否应该使用线程这样的更重要的问题在很大程序上取决于手头的应用程序。决定是否在应用程序中使用多线程的一种方法是,估计可以并行运行的代码量。并记住以下几点:

使用多线程不会增加 CPU 的能力。但是如果使用 JVM 的本地线程实现,则不同的线程可以在不同的处理器上同时运行(在多 CPU 的机器中),从而使多 CPU 机器得到充分利用。

如果应用程序是计算密集型的,并受 CPU 功能的制约,则只有多 CPU 机器能够从更多的线程中受益。

当应用程序必须等待缓慢的资源(如网络连接或数据库连接)时,或者当应用程序是非交互式的时,多线程通常是有利的。

基于 Internet 的软件有必要是多线程的;否则,用户将感觉应用程序反映迟钝。例如,当开发要支持大量客户机的服务器时,多线程可以使编程较为容易。在这种情况下,每个线 程可以为不同的客户或客户组服务,从而缩短了响应时间。 某些程序员可能在 C 和其他语言中使用过线程,在那些语言中对线程没有语言支持。这些程序员可能通常都被搞得对线程失去了信心。
分享到:
评论

相关推荐

    浅析JAVA多线程.pdf

    同步机制是Java多线程编程中的关键部分,用于解决多个线程对共享资源的访问冲突。Java提供了synchronized关键字来实现线程同步,它可以修饰方法或代码块,确保同一时刻只有一个线程能执行被修饰的代码。此外,还有...

    JAVA高级编程资料

    线程同步是多线程编程中的难点,包括synchronized关键字、wait/notify机制、Lock接口(如ReentrantLock)以及并发工具类(如Semaphore、CountDownLatch和CyclicBarrier)等,都是保证数据安全和避免竞态条件的关键。...

    JAVA 的多线程浅析.pdf

    多线程编程中常见的问题包括但不限于死锁、资源竞争和线程同步问题。程序员必须对线程之间的通信和资源共享有深刻的理解,以避免这些潜在的陷阱。Java通过提供synchronized关键字、wait()和notify()方法等工具,帮助...

    Java多线程文章系列.pdf

    ### Java多线程文章系列知识点概述 #### 一、Java多线程编程...以上是《Java多线程文章系列》的主要知识点概述,涵盖了从多线程的基础概念到高级应用,希望能帮助读者深入理解Java多线程编程的核心技术和实践技巧。

    浅析多核处理器条件下的Java编程.pdf

    在这样的背景下,理解和掌握Java的多线程编程技术变得至关重要。 1. Java语言的多线程基础 Java语言对多线程提供了内置支持,使得开发者可以轻松创建和管理并发执行的任务。多线程允许程序在同一时间执行多个不同的...

    浅析Java学习中的“短板”.pdf

    此外,还需要了解 Java 的高级技术,如多线程、网络编程、数据库编程等。 另外,初学者也需要了解 Java 的开发工具和环境,如 Eclipse、NetBeans、IntelliJ IDEA 等,以及 Java 的应用领域,如 Android 应用开发、...

    浅析Java多线程同步synchronized

    Java多线程同步synchronized是Java编程语言中最基本的同步机制之一。它通过锁机制来实现多线程之间的同步,确保多个线程访问共享资源时的安全性。 在Java中,synchronized关键字可以用来同步代码块或方法。同步代码...

    浅析Java_Concurrency

    java.util.concurrent.*包是Java并发编程中不可或缺的一部分,它提供了大量用于多线程编程的接口和类。这个包中的类主要包括同步器、并发集合、执行器框架、原子变量、锁等不同类型的并发工具。通过这些工具,Java...

    浅析java volatitle 多线程问题

    总之,`volatile`是Java多线程编程中的一种重要工具,它能确保共享变量在多线程环境中的可见性和有序性,但并不保证原子性。开发者应根据实际需求合理选择使用,以保证并发代码的正确性和高效性。

    浅析Java语言在计算机软件开发中的应用.pdf

    "浅析Java语言在计算机软件开发中的应用" Java语言是当前阶段的主流语言之一,具有入门较为简单、兼容性好、多线程、面向对象等优势。Java语言的优势使其被广泛应用到各行各业中,包括桌面程序的开发、嵌入式的...

    浅析Java语言在软件开发中的应用.pdf

    Java语言的主要特点是它可以实现在多个线程中转换,这项功能在之前的编程语言中并不存在,属于Java的独特之处。 Java的主要技术 Java的主要技术包括虚拟机、类装载器、Java class文件、Java API等。Java虚拟机的...

    Java互联网架构多线程并发编程原理及实战 视频教程 下载.zip

    Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....

    浅析Java中线程的创建和启动

    在Java编程语言中,线程的创建和启动是多任务并行处理的关键步骤。线程允许程序在同一时间内执行多个不同的任务,从而提高了程序的效率和响应性。下面将详细讲解如何在Java中创建和启动线程。 1. **线程的创建方式*...

    Java互联网架构多线程并发编程原理及实战 视频教程 下载4.zip

    Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....

    Java互联网架构多线程并发编程原理及实战 视频教程 下载2.zip

    Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....

    Java互联网架构多线程并发编程原理及实战 视频教程 下载3.zip

    Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....

    Java互联网架构多线程并发编程原理及实战 视频教程 下载1.zip

    Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....

    浅析Java中的final关键字Java开发Java经验技

    在Java编程语言中,`final`关键字扮演着一个至关重要的角色,它被广泛用于定义不可变对象、常量以及...无论是定义常量、防止方法重写、阻止类继承还是在多线程环境中确保数据一致性,`final`都是一个不可或缺的工具。

    浅析Java中如何实现线程之间通信

    Java中的线程间通信是多线程编程中的关键概念,它允许不同线程间共享数据、协调执行顺序,以实现复杂任务的同步。在Java中,有多种方式可以实现线程间的通信,以下将详细解释并举例说明这些方法。 1. **线程的join...

Global site tag (gtag.js) - Google Analytics