Java线程使用技巧学习(一)

Java线程使用技巧学习(一)

Java线程有哪些不太为人所知的技巧与用法?   萝卜白菜各有所爱。像我就喜欢Java。学无止境,这也是我喜欢它的一个原因。日常工作中你所用到的工具,通常都有些你从来没有了解过的东西,比方说某个方法或者是一些有趣的用法。比如说线程。没错,就是线程。或者确切说是Thread这个类。当我们在构建高可扩展性系统的时候,通常会面临各种各样的并发编程的问题,不过我们现在所要讲的可能会略有不同。   从本文中你将会看到线程提供的一些不太常用的方法及技术。不管你是初学者还是高级用户或者是Java专家,希望都能看一下哪些是你已经知道的,而哪些是刚了解的。如果你认为关于线程还有什么值得分享给大家的,希望能在下面积极回复。那我们就先开始吧。   初学者   1.线程名   程序中的每个线程都有一个名字,创建线程的时候会给它分配一个简单的Java字符串来作为线程名。默认的名字是”Thread-0″, “Thread-1″, “Thread-2″等等。现在有趣的事情来了——Thread提供了两种方式来设置线程名:

  • 线程构造函数,下面是最简单的一个实现:
class SuchThread extends Thread {

    Public void run() {
        System.out.println ("Hi Mom! " + getName());
    }

}

SuchThread wow = new SuchThread("much-name");
  • 线程名setter方法:
wow.setName(“Just another thread name”);

  没错,线程名是可变的。因此我们可以在运行时修改它的名字,而不用在初始化的时候就指定好。name字段其实就是一个简单的字符串对象。也就是说它能达到2³¹-1个字符那么长(Integer.MAX_VALUE)。这足够用了。注意这个名字并不是一个唯一性的标识,因此不同的线程也可以拥有同样的线程名。还有一点就是,不要把null用作线程名,否则会抛出异常(当然了,”null”还是可以的)。 使用线程名来调试问题   既然可以设置线程名,那么如果遵循一定的命名规则的话,出了问题的时候排查起来就能更容易一些。“Thread-6″这样的名字看起来就太没心没肺了,肯定有比它更好的名字。在处理用户请求的时候,可以将事务ID追加到线程名后面,这样能显著减少你排查问题的时间。

“pool-1-thread-1″ #17 prio=5 os_prio=31 tid=0x00007f9d620c9800 
nid=0x6d03 in Object.wait() [0x000000013ebcc000]

  “pool-1-thread-1″,这也太严肃了吧。我们来看下这是什么情况,给它起一个好点的名字:

Thread.currentThread().setName(Context + TID + Params + current Time, ...);
  

现在我们再来运行下jstack,情况便豁然开朗了:

”Queue Processing Thread, MessageID: AB5CAD, type: 
AnalyzeGraph, queue: ACTIVE_PROD, Transaction_ID: 5678956,
 Start Time: 30/12/2014 17:37″ #17 prio=5 os_prio=31 tid=0x00007f9d620c9800 
nid=0x6d03 in Object.wait() [0x000000013ebcc000]

如果我们能知道线程在做什么,这样当它出问题的时候,至少可以拿到事务ID来开始排查。你可以回溯这个问题,复现它,然后定位问题并搞定它。如果你想知道jstack有什么给力的用法,可以看下这篇文章。   2. 线程优先级   线程还有一个有意思的属性就是它的优先级。线程的优先级介于1 (MINPRIORITY)到10 (MAXPRIORITY)之间,主线程默认是5(NORM_PRIORITY)。每个新线程都默认继承父线程的优先级,因此如果你没有设置过的话,所有线程的优先级都是5。这个是通常被忽视的属性,我们可以通过getPriority()与setPriority()方法来获取及修改它的值。线程的构造函数里是没有这个功能的。 什么地方会用到优先级?   当然并不是所有的线程都是平等的,有的线程需要立即引起CPU的重视,而有些线程则只是后台任务而已。优先级就是用来把这些告诉给操作系统的线程调度器的。在Takipi中,这是我们开发的一错误跟踪及排查的工具,负责处理用户异常的线程的优先级是MAX_PRIORITY,而那些只是在上报新的部署情况的线程,它们的优先级就要低一些。你可能会觉得优先级高的线程从JVM的线程调度器那得到的时间会多一些。但其实并都是这样的。   在操作系统层面,每一个新线程都会对应一个本地线程,你所设置的Java线程的优先级会被转化成本地线程的优先级,这个在各个平台上是不一样的。在Linux上,你可以打开“-XX:+UseThreadPriorities”选项来启用这项功能。正如前面所说的,线程优先级只是你所提供的一个建议。和Linux本地的优先级相比,Java线程的优先级并不能覆盖全所有的级别(Linux共有1到99个优先级,线程的优先级在是-20到20之间)。最大的好处就是你所设定的优先级能在每个线程获得的CPU时间上有所体现,不过完全依赖于线程优先级的做法是不推荐的。

原文发布于微信公众号 - Java学习网(javalearns)

原文发表时间:2015-04-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java一日一条

Java高效并发之乐观锁悲观锁、(互斥同步、非互斥同步)

首先我们理解下两种不同思路的锁,乐观锁和悲观锁。 这两种锁机制,是在多用户环境并发控制的两种所机制。下面看百度百科对乐观锁和悲观锁两种锁机制的定义:

1663
来自专栏Albert陈凯

2018-08-02 IntelliJ IDEA - Debug 调试多线程程序IntelliJ IDEA - Debug 调试多线程程序

https://blog.csdn.net/nextyu/article/details/79039566

1862
来自专栏编程

PHP7 下的协程实现

前言 相信大家都听说过『协程』这个概念吧。 但是有些同学对这个概念似懂非懂,不知道怎么实现,怎么用,用在哪,甚至有些人认为yield就是协程! 我始终相信,如果...

3368
来自专栏PHP实战技术

PHP ob_start() 函数介绍

php ob_start 与 ob_end_flush() 是 php 的缓冲输出函数。

4019
来自专栏Java后端技术栈

Java多线程编程-(1)-线程安全和锁Synchronized概念

(1)在传统的操作系统中,程序并不能独立运行,作为资源分配和独立运行的基本单位都是进程。

853
来自专栏乐沙弥的世界

mongoDB简介及关键特性

761
来自专栏码生

StackNavigator in react-navigation 传参

使用上面的方法即可进行参数传递 但是我建议当想下一个界面传参数时,使用唯一字段标识

961
来自专栏测试驿栈

Jmeter(七)_if控制器+循环控制器+计数器控制接口分支

最近查阅了一下网上关于if控制器的文章,大同小异,几乎找不到原创,于是决定自己写一篇

1K2
来自专栏ascii0x03的安全笔记

Lua编写wireshark插件初探——解析Websocket上的MQTT协议

一、背景 最近在做物联网流量分析时发现, App在使用MQTT协议时往往通过SSL+WebSocket+MQTT这种方式与服务器通信,在使用SSL中间人截获数据...

71614
来自专栏阿杜的世界

Spring Boot:定制URL匹配规则

构建web应用程序时,并不是所有的URL请求都遵循默认的规则。有时,我们希望RESTful URL匹配的时候包含定界符“.”,这种情况在Spring中可以称之为...

1263

扫码关注云+社区

领取腾讯云代金券