`

多线程使用中的一些好习惯

 
阅读更多

本文主要介绍个人在多线程使用和调优中总结一些线程使用比较好的习惯,方便大家在线程出现问题时排查,好习惯是高效率的基础

几个习惯分别为设置线程名处理interrupt、使用ThreadLocal

其他下次再写吧

 

1、设置线程名

使用过VisualVM或其他java自带工具或是thread dump的朋友都能体会到如果线程没有设置名称,要进行性能问题排查和调优那是相当头大的一件事,下面先贴一张VisualVM的Threads运行图


上图中几个紫色的线程是自定义线程,可以看出前三个线程被手动命名过,后三个线程为自动命令。在这个图中还不是很容易看出差别,因为它只是个简单的main函数,线程个数也有限。但如果对于一个较大的软件或是web程序,线程数成百上千,自动的命名方法你还能识别出哪个线程是你自己的吗???

下面介绍几种命名线程的方法,主要有三种:

(1) new Thread("threadName")

(2) thread.setName("threadName")

(3)子类的构造函数中super(threadName),其实跟第一种一样

 

具体代码可以查看本文最后源码,可以运行其中的setThreadNameExam()函数;

 

2、处理interrupt

通常将较耗时或较复杂操作单独放在线程中,所以线程中极有可能出现大循环或较耗时,如果这时候突然中断,默认线程退出是不会有其他响应的,对于线程中断有三种方法可以处理:

(1) 使用

if (Thread.interrupted()) {
	doSomeThing();
}

处理

(2) 捕获异常

try {
	doXXX();
} catch(InterruptedException e) {
	// handle Exception
} catch(Exception e) {
	// handle Exception
}

(3) 抛出异常

public void foo() throws InterruptedException {
	if(Thread.interrupted()) {
		throw new InterruptedException();
	}
}

具体使用可以查看本文最后的源码,可以运行其中的 threadInterruptExam();

 

3、使用ThreadLocal

ThreadLocal

 

本文示例代码如下

    private static int       count1InInterruptExam = 0, count2InInterruptExam = 0;

    public static void main(String[] args) {
        // setThreadNameExam();
        threadInterruptExam();
    }

    public static void setThreadNameExam() {
        /** 未设置线程名 **/
        nonNamedThread();

        /** 在new thread时设置线程名,有多种构造函数,可以参考Thread java源代码中名为init的私有方法 **/
        namedThread1();

        /** 通过Thread的setName方法设置线程名 **/
        namedThread2();

        /** 继承自Thread的子类,可以在构造函数中使用super(name)设置线程名 **/
        namedThread3();
    }

    public static void nonNamedThread() {
        for (int i = 0; i < 3; i++) {
            Thread nonNamedThread = new Thread() {

                public void run() {
                    threadLogic();
                }
            };
            nonNamedThread.start();
        }
    }

    public static void namedThread1() {
        Thread namedThread1 = new Thread("namedThread1 named when new thread") {

            public void run() {
                threadLogic();
            }
        };
        namedThread1.start();

    }

    public static void namedThread2() {
        Thread namedThread2 = new Thread() {

            public void run() {
                threadLogic();
            }
        };
        namedThread2.setName("namedThread2 named  by Thread.setName");
        namedThread2.start();
    }

    public static void namedThread3() {
        class NamedThread extends Thread {

            public NamedThread(){
                super("namedThread");
            }

            public NamedThread(String threadName){
                super(threadName);
            }

            public void run() {
                threadLogic();
            }
        }
        ;

        NamedThread namedThread3 = new NamedThread("namedThread3 named by use super in constructor");
        namedThread3.start();
    }

    public static void threadLogic() {
        try {
            Thread.sleep(100000);
            System.out.println("finished");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 线程interrupt举例
     * 通常可用于循环中较长时间操作,对中断进行响应
     */
    public static void threadInterruptExam() {
        count1InInterruptExam = 0;
        count2InInterruptExam = 0;
        Thread threadHasHandedInterrupt = new Thread("thread has handed interrupt") {

            public void run() {
                for (int i = 1; i <= 100000000; i++) {
                    if (i % 3 == 0) {
                        count1InInterruptExam++;
                    } else if (i % 3 == 1) {
                        count1InInterruptExam--;
                    }
                    if (Thread.interrupted()) {
                        System.out.println("thread be interrupted, set count to 123456");
                        count1InInterruptExam = 123456;
                    }
                }
            }
        };
        threadHasHandedInterrupt.start();
        Thread threadNotHandInterrupt = new Thread("thread does not handle interrupt") {

            public void run() {
                for (int i = 1; i <= 100000000; i++) {
                    if (i % 3 == 0) {
                        count2InInterruptExam++;
                    } else if (i % 3 == 1) {
                        count2InInterruptExam--;
                    }
                }
            }
        };
        threadNotHandInterrupt.start();

        try {
            Thread.sleep(1 * 1000);
            threadHasHandedInterrupt.interrupt();
            threadNotHandInterrupt.interrupt();
            Thread.sleep(1 * 1000);
            System.out.println("count in thread that has handed interrupt :" + count1InInterruptExam);
            System.out.println("count in thread that does not hand interrupt :" + count2InInterruptExam);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

其中查看Thread的java源代码可以查看:http://trinea.iteye.com/blog/1351233

  • 大小: 58.3 KB
分享到:
评论

相关推荐

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

    通过这些实战练习,读者能够更好地理解多线程编程中的挑战和解决方案。 本书还涉及到了Java并发工具类,如Semaphore信号量、CyclicBarrier栅栏、CountDownLatch倒计时器等,这些都是Java并发编程中的重要工具,可以...

    多线程同步利用ccriticalsection

    - `CCriticalSection`是MFC中的一个类,它封装了Windows API的`InitializeCriticalSection`、`EnterCriticalSection`、`LeaveCriticalSection`和`DeleteCriticalSection`函数,使得在MFC程序中使用线程同步更加方便...

    多线程在对话框中的创建

    通过分析和运行这个示例,你可以更好地理解和掌握在对话框中创建和管理多线程的方法。 总之,多线程在对话框中的应用可以提高用户体验,但同时也增加了程序设计的复杂性。理解线程的生命周期、同步机制以及如何与...

    VC多线程实例

    在VC++编程环境中,多线程技术是一种关键的性能优化手段,它允许程序同时执行多个任务,提升程序的效率和响应性。本实例将深入探讨如何在Visual...通过实践“VC多线程实例”中的代码,你将能更好地理解和运用这些概念。

    mongoose 多线程httpserver v6.15

    VC6虽然是一款较老的开发工具,但仍然有开发者使用它来构建项目,这可能是因为它对于某些特定的项目或者库有较好的兼容性,或者开发者对其有深厚的理解和习惯。在VC6中将mongoose源码转换为C++工程,意味着开发者...

    java 多线程的小游戏 Java 课程设计 Java毕业设计 多线程的小游戏 经典

    在这个课程设计或毕业设计项目中,学生通常会被要求实现一个能够展示多线程特性的游戏,比如经典的“猜数字”或者“抢红包”等,这些游戏都需要多个线程协作来完成。 首先,我们来看多线程的基本概念。在Java中,...

    windows多线程con.rar_Windows多线程_windows 多线程

    在Windows操作系统中,多线程是一种程序设计技术,允许单个进程内同时执行多个不同的代码段,即线程。...此外,了解并遵循良好的编程习惯,如减少全局变量的使用,可以降低多线程编程的复杂性和错误率。

    VC6.0调用大漠插件的例子 多线程

    在IT行业中,开发人员经常需要在不同的环境中集成各种工具和插件来提升工作效率或实现特定功能。本案例涉及的是在古老的Visual C++ 6.0...对于想要深入理解VC6.0和多线程应用的开发者来说,这是一个很好的实践项目。

    VB多线程源码

    通过研究这些源码,开发者可以更好地理解VB.NET中多线程的实现细节,提升自己的编程技能。 请注意,由于VB.NET的多线程涉及到的概念和技巧较多,实际使用时需要根据具体需求灵活应用,并结合适当的错误处理和性能...

    POSIX多线程程序设计中文版

    - **定义**:多线程是指在单个程序中同时执行多个线程的能力,这些线程共享相同的内存空间。 - **优点**: - **资源利用率高**:可以更高效地利用CPU资源。 - **响应速度快**:通过并发执行任务来减少等待时间。...

    C#多线程学习

    ### C#多线程学习知识点概述 #### 一、多线程的基本概念 - **进程**: 当一个程序...然而,多线程编程也有其挑战,特别是如何避免线程间的资源竞争和死锁等问题,这需要开发者具备良好的设计思路和严谨的编码习惯。

    多线程编程指南

    ### 多线程编程指南知识点概述 #### 一、多线程编程概念与术语 **1.1 什么是多线程** 多线程是指在单个进程中能够同时运行多个线程的技术。...此外,合理的设计和良好的编码习惯也是保证多线程程序质量的关键。

    Storm the Gates, windowsAPI 多线程

    在C++中,可以使用`&lt;thread&gt;`库进行多线程编程。然而,这里我们讨论的是如何使用Windows API,因此我们需要包含`Windows.h`头文件,并使用Windows API函数来创建和管理线程。例如,我们创建线程时,可以定义一个函数...

    DEMO-多循环应用程序构架.rar_DEMO_labview多线程框架

    这个DEMO示例可能包含了上述部分或全部知识点,通过逐步学习和实践,初学者可以更好地理解和掌握LabVIEW中的多线程编程。它将提供一个直观的起点,帮助开发者建立多线程应用的基础,并为更复杂的并发编程打下坚实...

    win32控制台输出多线程socket编程-client

    在本文中,我们将深入探讨如何在Windows环境下使用Win32 API和套接字(socket)进行多线程编程,特别是创建一个客户端应用。这个示例代码展示了如何建立一个客户端,它能够连接到指定的服务器IP地址(在这个例子中是...

    android 多线程断点下载

    使用`finally`块进行资源清理是个好习惯。 10. **安全性**:在处理用户数据时,应确保文件操作的安全性,避免权限泄露。此外,对于下载的文件,应该进行安全检查,防止恶意代码的植入。 以上就是多线程断点续传在...

    Java之多线程学习代码

    通过学习和实践这些代码示例,你可以更好地理解和掌握Java多线程的各个方面,从而能够编写出高效、稳定的多线程程序。在实践中,还需要注意性能优化、死锁预防、线程安全的编程习惯,以及如何有效地利用Java提供的...

    Python中用多线程爬取网页图像的好处.pdf

    总的来说,Python中的多线程爬取网页图像能够为网络数据的自动化采集提供更为高效和合理的解决方案,有助于更好地利用计算资源,提高程序的执行速度和效率。通过理论研究与实际案例相结合的方式,我们能够更深入地...

    Apache log4cxx在C++多进程多线程下的使用.pdf

    Apache log4cxx 在 C++ 多进程多线程下的使用 Apache log4cxx 是 Apache Logging Services 三个日志记录项目之一,完全开源组件。是著名的日志记录组件 log4j 的 C++ 移植版,用于为 C++ 程序提供日志功能,以便...

Global site tag (gtag.js) - Google Analytics