Java 之多线程

在这篇文章里,我们关注多线程。多线程是一个复杂的话题,包含了很多内容,这篇文章主要关注线程的基本属性、如何创建线程、线程的状态切换以及线程通信,我们把线程同步的话题留到下一篇文章中。

线程是操作系统运行的基本单位,它被封装在进程中,一个进程可以包含多个线程。即使我们不手动创造线程,进程也会有一个默认的线程在运行。

对于JVM来说,当我们编写一个单线程的程序去运行时,JVM中也是有至少两个线程在运行,一个是我们创建的程序,一个是垃圾回收。

 线程基本信息

 我们可以通过Thread.currentThread()方法获取当前线程的一些信息,并对其进行修改。

 我们来看以下代码:

Java 之多线程
Java 之多线程
 1 public class test_1 {
 2     
 3     public static void main(String[] args){
 4         //查看并修改当前线程的属性        
 5         String name = Thread.currentThread().getName();
 6         int priority = Thread.currentThread().getPriority();
 7         String groupName = Thread.currentThread().getThreadGroup().getName();
 8         //该线程是否为守护线程。
 9         boolean isDaemon = Thread.currentThread().isDaemon();
10         //测试线程是否处于活动状态。如果线程已经启动且尚未终止,则为活动状态。 
11         boolean isAlive = Thread.currentThread().isAlive();
12         System.out.println("Thread Name:"+name);
13         System.out.println("poiority:"+priority);
14         System.out.println("groupName:"+groupName);
15         System.out.println("isDaemon:"+isDaemon);
16         System.out.println("isAlive:"+isAlive);
17         System.out.println("-------------");
18         Thread.currentThread().setName("Test_修改后名字");
19         Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
20         name = Thread.currentThread().getName();
21         priority = Thread.currentThread().getPriority();
22         groupName = Thread.currentThread().getThreadGroup().getName();
23         isDaemon = Thread.currentThread().isDaemon();
24         System.out.println("Thread Name:" + name);
25         System.out.println("Priority:" + priority);
26 
27     }
28     
29     
30 }
View Code
Java 之多线程

其中列出的属性说明如下:

  • GroupName,每个线程都会默认在一个线程组里,我们也可以显式的创建线程组,一个线程组中也可以包含子线程组,这样线程和线程组,就构成了一个树状结构。
  • Name,每个线程都会有一个名字,如果不显式指定,那么名字的规则是“Thread-xxx”。
  • Priority,每个线程都会有自己的优先级,JVM对优先级的处理方式是“抢占式”的。当JVM发现优先级高的线程时,马上运行该线程;对于多个优先级相等的线程,JVM对其进行轮询处理。Java的线程优先级从1到10,默认是5,Thread类定义了2个常量:MIN_PRIORITY和MAX_PRIORITY来表示最高和最低优先级。

我们可以看下面的代码,它定义了两个不同优先级的线程:

Java 之多线程
Java 之多线程
 1 public class test_2 {
 2     
 3     public static void main(String[] args)
 4     {
 5         Thread thread1 = new Thread("low")
 6         {
 7             public void run(){
 8                 for(int i=0;i<5;i++){
 9                     System.out.println(this.getName() +" is running!");
10                 }
11             }
12         };
13         
14         Thread thread2 = new Thread("high"){
15             public void run(){
16                 for(int i=0;i<5;i++){
17                     System.out.println(this.getName() +" is running!");
18                 }
19             }
20         };
21         thread1.setPriority(Thread.MIN_PRIORITY);
22         thread2.setPriority(Thread.MAX_PRIORITY);
23         thread1.start();
24         thread2.start();
25     }
26 
27 }
View Code
Java 之多线程

每个线程执行时都有一个优先级的属性,优先级高的线程可以获得较多的执行机会,而优先级低的线程则获得较少的执行机会。与线程休眠类似,线程的优先级仍然无法保障线程的执行次序。只不过,优先级高的线程获取CPU资源的概率较大,优先级低的也并非没机会执行

每个线程默认的优先级都与创建它的父线程具有相同的优先级,在默认情况下,main线程具有普通优先级。

Thread类提供了setPriority(int newPriority)和getPriority()方法来设置和返回一个指定线程的优先级,其中setPriority方法的参数是一个整数,范围是1~·0之间,也可以使用Thread类提供的三个静态常量:

MAX_PRIORITY   =10

MIN_PRIORITY   =1

NORM_PRIORITY   =5

  • isDaemon,这个属性用来控制父子线程的关系,如果设置为true,当父线程结束后,其下所有子线程也结束,反之,子线程的生命周期不受父线程影响。

我们来看下面的例子:

Java 之多线程
Java 之多线程
 1 public class test_3 {
 2     
 3     public static void main(String[] args)
 4     {
 5         Thread thread = new Thread("daemon")
 6         {
 7             public void run()
 8             {
 9                 Thread subThread = new Thread("sub")
10                 {
11                     public void run()
12                     {
13                         for(int i=0;i<100;i++)
14                         {
15                             System.out.println(this.getName()+" is running! "+i);
16                         }
17                     }
18                 };
19                 //对比注释该语句
20                 subThread.setDaemon(true);
21                 System.out.println("subThread isDaemon:"+subThread.isDaemon());
22                 subThread.start();
23                 System.out.println("main thread is end!");
24             
25             }        
26         };
27         thread.start();
28     }
29 
30 }
View Code
Java 之多线程

 

上面代码的运行结果,对比注释掉语句//subThread.setDaemon(true);

如果 subThread isDaemon:false, 子进程会全部执行完

如果 subThread isDaemon:true, 子进程很快就结束了

 

 扩展:

JAVA并发编程——守护线程(Daemon Thread)

在Java中有两类线程:用户线程 (User Thread)、守护线程 (Daemon Thread)。

所谓守护线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。因 此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止

用户线程和守护线程两者几乎没有区别,唯一的不同之处就在于虚拟机的离开:如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了。 因为没有了被守护者,守护线程也就没有工作可做了,也就没有继续运行程序的必要了。

将线程转换为守护线程可以通过调用Thread对象的setDaemon(true)方法来实现。在使用守护线程时需要注意一下几点:

(1) thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。 

(2) 在Daemon线程中产生的新线程也是Daemon的。

(3) 守护线程应该永远不去访问固有资源,如文件、数据库,因为它会在任何时候甚至在一个操作的中间发生中断。

Java 之多线程,布布扣,bubuko.com

Java 之多线程

上一篇:Exp8 Web综合 20181308


下一篇:CTF web之旅44