线程基础知识系列(二)线程的管理

简介:

说明了线程的2种创建和启动,join(),daemon线程,Callable 
任务。

本文的主要内容

  1. 线程的状态

  2. 线程的优先级

  3. sleep vs wait

  4. 线程的流程控制

  5. Interrupt

  6. yield让出你的CPU



1.线程的状态

以《线程基础知识系列(一)线程的创建和启动》这张图,是程序的运行时线程信息截图。有main线程,user Threads,daemon Threads。现在咱们把重点放在线程状态上(RUNNING,WAIT,SLEEPING...)

线程的状态有哪些?状态转换图是怎么样的?

wKiom1dvlgej-_eRAABM-qR14cc719.png

线程状态转换图

wKiom1dv1sHRmhKcAAJRalKoBdc747.png


状态信息是枚举类型,线程状态分别是:New,RUNNABLE,BLOCKED,WAITING,TIMED_WAITED,TERMINATED.

wKiom1dv14iQKzEgAAI4CDOBw0U848.png

1.1 TimedWaitThreadDemo.java ,主要演示了TIMED_WAITING状态的触发时机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package  com.threadexample.mgr;
 
import  java.util.concurrent.TimeUnit;
 
/**
  * Created by Administrator on 2016/6/26.
  */
public  class  TimedWaitThreadDemo {
     public  static  void  main(String[] args)  throws  InterruptedException {
         Thread mythread =  new  Thread( new  Runnable() {
             @Override
             public  void  run() {
                 System.out.println( "begin sleep start" );
                 try  {
                     TimeUnit.SECONDS.sleep( 5 );
                 catch  (InterruptedException e) {
                     e.printStackTrace();
                 }
                 System.out.println( "end sleep start" );
             }
         });
 
         mythread.start();
         TimeUnit.SECONDS.sleep( 1 );
         System.out.println( "mythread.state:" +mythread.getState());
     }
}

执行结果

-----------------------

begin sleep start
mythread.state:TIMED_WAITING
end sleep start

--------------------------


1.2 WaitThreadDemo.java ,主要演示了WAITING状态的触发时机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package  com.threadexample.mgr;
 
import  java.util.concurrent.TimeUnit;
 
/**
  * Created by Administrator on 2016/6/26.
  */
public  class  WaitThreadDemo {
     private  final  static  Object lock =  new  Object();
     public  static  void  main(String[] args)  throws  InterruptedException {
         Thread mythread =  new  Thread( new  Runnable() {
             @Override
             public  void  run() {
                synchronized  (lock){
                    try  {
                        lock.wait();
                    catch  (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
             }
         });
         mythread.start();
         TimeUnit.SECONDS.sleep( 1 ); //休眠1秒,保证能进入同步块
         System.out.println( "mythread.state:" +mythread.getState());
     }
}

执行结果

----------------

mythread.state:WAITING

----------------

1.3BlockedThreadDemo.java,主要演示了BLOCKED状态的触发时机。需要涉及多个线程资源争用,所以需要多个线程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package  com.threadexample.mgr;
 
import  java.util.concurrent.TimeUnit;
 
/**
  * Created by Administrator on 2016/6/26.
  */
public  class  BlockedThreadDemo {
     private  final  static  Object lock =  new  Object();
     public  static  void  main(String[] args)  throws  InterruptedException {
         Runnable ruunnble =  new  Runnable() {
             @Override
             public   void  run() {
                 synchronized  (lock){
                     System.out.println(Thread.currentThread().getName()+ "开始业务操作" );
                     try  {
                         TimeUnit.SECONDS.sleep( 2 );
                     catch  (InterruptedException e) {
                         e.printStackTrace();
                     }
                     System.out.println(Thread.currentThread().getName()+ "完成业务操作" );
             }
             }
         };
         Thread mythread =  new  Thread(ruunnble);
         Thread mythread2 =  new  Thread(ruunnble);
         mythread.start();
         mythread2.start();
         System.out.println( "mythread.state:"  + mythread.getState());
         System.out.println( "mythread2.state:" +mythread2.getState());
     }
}

执行结果

-------------------------

Thread-0开始业务操作
mythread.state:RUNNABLE
mythread2.state:BLOCKED
Thread-0完成业务操作
Thread-1开始业务操作
Thread-1完成业务操作

-------------------------

2.线程的优先级

线程有个优先级属性,优先级是从1到10的整数类型。

Thread Priority Constants Integer Value
MIN_PRIORITY 1
NORM_PRIORITY 5
MAX_PRIORITY 10

理论上来说,优先级越高,获取CPU的的时间越大,这仅仅是概率问题,并不能保证优先级越高的线程一定先执行。线程的优先级,对于调度器而言,仅仅相当于一个提示器的作用,具体如何执行,还要看CPU的心情。

需要说明的事,依靠优先级的顺序来决定线程的执行顺序,是不靠谱的。线程的优先级是依靠操作系统底层调度的,由于操作系统的调度方式也存在差异,所以线程优先级的执行行为也会存在差异。

JAVA 提供了setPriority() 和getPriority()管理线程。

PriorityThreadDemo.java 演示了线程优先级的管理,通过分析结果也验证了,优先级并不能保证线程的执行顺序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package  com.threadexample.mgr;
import  java.util.ArrayList;
import  java.util.List;
public  class  PriorityThreadDemo {
     public  static  void  main(String[] args) {
         Runnable ruunnble =  new  Runnable() {
             @Override
             public   void  run() {
                 System.out.println(Thread.currentThread().getName()+ "\t优先级:" +Thread.currentThread().getPriority()+ "\t执行完成" );
             }
         };
 
         List<Thread> tasks =  new  ArrayList<Thread>();
         for ( int  i=Thread.MIN_PRIORITY;i<=Thread.MAX_PRIORITY;i++){
             Thread thread =  new  Thread(ruunnble);
             thread.setPriority(i);
             tasks.add(thread);
         }
 
         for (Thread thread:tasks){
             thread.start();
         }
     }
}

执行结果

--------------------

Thread-0    优先级:1    执行完成
Thread-4    优先级:5    执行完成
Thread-2    优先级:3    执行完成
Thread-1    优先级:2    执行完成
Thread-3    优先级:4    执行完成
Thread-5    优先级:6    执行完成
Thread-6    优先级:7    执行完成
Thread-8    优先级:9    执行完成
Thread-9    优先级:10    执行完成
Thread-7    优先级:8    执行完成

--------------------

3.sleep vs wait

sleep()和wait()方法,对线程的影响“当前线程停止执行”。但他们之间的存在本质区别

区别
wait
sleep
Class  belongs 属于java.lang.Object class  属于java.lang.Thread class

Context

(上下文)

只能在Synchronized context 
中调用。也就是常见的synchronized快中。
任意上下文
Locking (锁管理)
释放锁 不释放锁

Wake up condition

唤醒条件

被另外线程,通过调用notify() or notifyAll() 唤醒
interrupt 
和时间过期机制
Execution (执行时机)
线程间的通信
属于Thread的静态方法

4.线程的流程控制

SN


Methods with Description

1

暂停

public void suspend()

This method puts a thread in suspended state and can be resumed using resume() method.

2

停止

public void stop()

This method stops a thread completely.

3

恢复

public void resume()

This method resumes a thread which was suspended using suspend() method.

4

等待

public void wait()

Causes the current thread to wait until another thread invokes the notify().

5

唤醒

public void notify()

Wakes up a single thread that is waiting on this object's monitor.

遗憾的是suspend( ), resume( ), and stop( ) 这些方法都被弃用了,不建议使用。

ThreadControlDemo.java提供了暂停,恢复,停止的功能。有一点说明,必须保证状态信息的同步。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package  com.threadexample.mgr;
 
class  RunnableDemo  implements  Runnable {
     public  Thread t;
     private  String threadName;
     boolean  suspended =  false ;
 
     RunnableDemo(String name) {
         threadName = name;
         System.out.println( "Creating "  + threadName);
     }
 
     public  void  run() {
         System.out.println( "Running "  + threadName);
         try  {
             for  ( int  i =  10 ; i >  0 ; i--) {
                 System.out.println( "Thread: "  + threadName +  ", "  + i);
                 // Let the thread sleep for a while.
                 Thread.sleep( 300 );
                 synchronized  ( this ) {
                     while  (suspended) {
                         wait();
                     }
                 }
             }
         catch  (InterruptedException e) {
             System.out.println( "Thread "  + threadName +  " interrupted." );
         }
         System.out.println( "Thread "  + threadName +  " exiting." );
     }
 
     public  void  start() {
         System.out.println( "Starting "  + threadName);
         if  (t ==  null ) {
             t =  new  Thread( this , threadName);
             t.start();
         }
     }
 
     void  suspend() {
         suspended =  true ;
     }
 
     synchronized  void  resume() {
         suspended =  false ;
         notify();
     }
}
 
public  class  ThreadControlDemo {
     public  static  void  main(String args[]) {
 
         RunnableDemo R1 =  new  RunnableDemo( "Thread-1" );
         R1.start();
 
         RunnableDemo R2 =  new  RunnableDemo( "Thread-2" );
         R2.start();
 
         try  {
             Thread.sleep( 1000 );
             R1.suspend();
             System.out.println( "Suspending First Thread" );
             Thread.sleep( 1000 );
             R1.resume();
             System.out.println( "Resuming First Thread" );
             R2.suspend();
             System.out.println( "Suspending thread Two" );
             Thread.sleep( 1000 );
             R2.resume();
             System.out.println( "Resuming thread Two" );
         catch  (InterruptedException e) {
             System.out.println( "Main thread Interrupted" );
         }
 
         try  {
             System.out.println( "Waiting for threads to finish." );
             R1.t.join();
             R2.t.join();
         catch  (InterruptedException e) {
             System.out.println( "Main thread Interrupted" );
         }
         System.out.println( "Main thread exiting." );
     }
}

5.Interrupt

interrupt方法用于中断线程。调用该方法的线程的状态为将被置为"中断"状态。

注意:线程中断仅仅是置线程的中断状态位,不会停止线程。需要用户自己去监视线程的状态为并做处理。支持线程中断的方法(也就是线程中断后会抛出interruptedException的方法)就是在监视线程的中断状态,一旦线程的中断状态被置为“中断状态”,就会抛出中断异常。


InterruptDemo.java展示了Thread.interrupted()的使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package  com.threadexample.mgr;
 
public  class  InterruptDemo {
     public  static  void  main(String[] args) {
         System.out.println( "#1:"  + Thread.interrupted());
 
         // Now interrupt the main thread
         Thread.currentThread().interrupt();
 
         // Check if it has been interrupted
         System.out.println( "#2:"  + Thread.interrupted());
 
         // Check again if it has been interrupted
         System.out.println( "#3:"  + Thread.interrupted());
     }
}

执行结果

----------------------

#1:false
#2:true
#3:false

----------------------

分析结果得知,Thread.interrupted()会清理中断标记。

InterruptDemo2.java展示了isInterrupted()的使用。第一次调用和第二次调用返回结果一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package  com.threadexample.mgr;
public  class  InterruptDemo2 {
     public  static  void  main(String[] args) {
         Thread th1 =  new  Thread( new  Runnable() {
             @Override
             public  void  run() {
                 Thread currentThread = Thread.currentThread();
                 currentThread.interrupt();
                 System.out.println( "isInterrupted()#1=" +currentThread.isInterrupted());
                 System.out.println( "isInterrupted()#2=" +currentThread.isInterrupted());
             }
         });
         th1.start();
     }
}

执行结果

----------------------

isInterrupted()#1=true
isInterrupted()#2=true

---------------------

isInterrupted()  VS interrupted() 

方面
isInterrupted() interrupted()
不同点

Thread 静态方法。返回结果决定于当前线程的是否被中断。

该方法会清理线程的中断状态


Thread的实例方法。不会被清理。
相似点

public static boolean interrupted () {
     return currentThread().isInterrupted(true);
}


调用同一个方法,参数不同而已

private native boolean isInterrupted( boolean ClearInterrupted);

public boolean isInterrupted () {
     return isInterrupted( false);
}

6.yield ()放弃你的CPU

yield(),是一个影响调度器的hint,作用是临时放弃CPU资源,允许其他线程执行。

YieldDemo.java,展示了yield()的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package  com.threadexample.mgr;
 
/**
  * Created by Administrator on 2016/6/26.
  */
public  class  YieldDemo  implements  Runnable {
 
     Thread t;
 
     YieldDemo(String str) {
 
         t =  new  Thread( this , str);
         // this will call run() function
         t.start();
     }
 
     public  void  run() {
 
         for  ( int  i =  0 ; i <  5 ; i++) {
             // yields control to another thread every 5 iterations
             if  ((i %  5 ) ==  0 ) {
                 System.out.println(Thread.currentThread().getName() +  " yielding control..." );
    /* causes the currently executing thread object to temporarily
    pause and allow other threads to execute */
                 Thread.yield();
             }
         }
 
         System.out.println(Thread.currentThread().getName() +  "  has finished executing." );
     }
 
     public  static  void  main(String[] args) {
         new  YieldDemo( "Thread 1" );
         new  YieldDemo( "Thread 2" );
         new  YieldDemo( "Thread 3" );
     }
}

结果

----------

Thread 1 yielding control...
Thread 3 yielding control...
Thread 2 yielding control...
Thread 3  has finished executing.
Thread 1  has finished executing.
Thread 2  has finished executing.

---------

但是执行了几次,结果一直在变化。yield根本不能保证执行顺序。

其他

Thread.setName()

Thread.isAlive()

ThreadGroup

Thread.activeCount()



本文转自 randy_shandong 51CTO博客,原文链接:http://blog.51cto.com/dba10g/1793099,如需转载请自行联系原作者

相关文章
|
存储 弹性计算 运维
2024阿里云服务器经济型e实例规格云服务器性能介绍
2024阿里云服务器经济型e实例规格云服务器性能介绍,阿里云服务器ECS推出经济型e系列,经济型e实例是阿里云面向个人开发者、学生、小微企业,在中小型网站建设、开发测试、轻量级应用等场景推出的全新入门级云服务器,CPU采用Intel Xeon Platinum架构处理器
|
消息中间件 Linux API
Linux c/c++之IPC进程间通信
这篇文章详细介绍了Linux下C/C++进程间通信(IPC)的三种主要技术:共享内存、消息队列和信号量,包括它们的编程模型、API函数原型、优势与缺点,并通过示例代码展示了它们的创建、使用和管理方法。
381 0
Linux c/c++之IPC进程间通信
|
自然语言处理 API Python
一文告诉你如何用 Python 操作 ChatGPT
一文告诉你如何用 Python 操作 ChatGPT
449 2
|
Java API 开发工具
如何通过淘宝商品详情接口实现商品 SKU、优惠价、价格等参数的实时更新?
要合法获取淘宝商品详情数据,首先需通过淘宝开放平台注册开发者账号并获得App Key与App Secret。接着根据业务需求申请对应的商品详情数据接口权限,并通过官方文档了解接口详情。获取访问令牌后,按照文档构建请求URL并附加必要参数及令牌以调用接口。此外,考虑使用淘宝提供的SDK简化开发流程,如Python SDK等。体验API:b.mrw.so/2Pv6Qu。
|
机器学习/深度学习 监控
分段微调
【10月更文挑战第3天】
372 0
|
SQL 关系型数据库 分布式数据库
用Ganos低代码实现免切片遥感影像浏览
本文介绍了一种基于PolarDB兼容PostgreSQL 14的高效栅格数据管理和可视化方案。推荐配置包括4核CPU、16GB内存、50GB磁盘等。通过创建扩展并上传影像至OSS,利用SQL语句完成数据导入、镶嵌、匀色及金字塔构建。重点介绍了使用ST_AsTile函数动态生成标准瓦片的方法,支持多种格式和增强方式。前端通过Python实现服务接口,实现实时、高效的数据展示。此方案具有实时性强、存储成本低等优点,适合快速可视化大量栅格数据。
222 0
|
自然语言处理 数据可视化 算法
【传知代码】私人订制词云图-论文复现
本文介绍了词云图的原理和生成步骤,包括分词、统计词频、去除停用词等,并提供了Python实现示例,利用`wordcloud`和`jieba`库。此外,还分享了技巧,如处理中文乱码、选择背景图、词库转换及自定义文字颜色。词云图能直观展示文本关键信息,适用于数据分析和文本挖掘,但也有其局限性,如无法显示词汇的语法关系。源码和更多资源可在文章附件获取。
513 0
【传知代码】私人订制词云图-论文复现
|
机器学习/深度学习 数据采集 存储
百川智能发布超千亿大模型Baichuan 3,中文评测超越GPT-4
百川智能发布大语言模型Baichuan 3,参数超千亿,表现出色。在CMMLU、GAOKAO等中文任务评测中超越GPT-4,且在MATH、HumanEval等专项评测中证明其自然语言处理和代码生成实力。Baichuan 3在医疗领域,如MCMLE、MedExam等评测中成绩突出,成为中文医疗任务的最佳模型。此外,它通过“迭代式强化学习”提升语义理解和生成能力,诗词创作能力远超其他模型。Baichuan 3的推出标志着百川智能在大模型技术上的新里程碑。
355 0
|
存储 算法 数据挖掘
Pandas处理时间序列数据的20个关键知识点
Pandas处理时间序列数据的20个关键知识点
587 0
Pandas处理时间序列数据的20个关键知识点
|
安全 小程序 搜索推荐
HTTPS证书是什么?
HTTPS证书准确来说是SSL证书(安全套接字层)或数字证书负责在您的网站和访问者浏览器之间创建安全连接。它确保网站和浏览器之间传递的所有数据保持私密和安全。当您使用SSL加密时,黑客将无法窃取您的私人信息,包括信用卡和借记卡号码、登录详细信息。
1341 0
HTTPS证书是什么?