多线程的两种方式实现方法:1.thread 2.runnable

 

两种方式的比较:

Runnable方式可以避免thread方式由于java单继承特性带来的缺陷

Runnable的代码可以被多个线程(thread实例)共享,适合于多个线程处理同一资源的情况

 

线程的生命周期:

创建——就绪——阻塞——运行——终止

 

创建:调用start方法到就绪状态。

就绪:创建了线程对象后,调用了线程的start()方法(注意:此时线程只是进入了 线程队列,等待获取CPU服务,具备了运行的条件,但并不一定已经开始运行了)获取cup才进入运行状态。

 

阻塞:一个正在执行的线程在某些情况下,由于某种原因而暂时让出了CPU资源,暂停了自己的执行,便进入了阻塞状态,如调用了sleep方法。从而让其他资源执行。

 

终止:线程的run()方法执行完毕,或者线程调用了stop()方法,线程便进入终止状态。

 

Java线程有两类:

用户线程:运行在前台。

守护线程:运行在后台,为其他前台线程服务。有人这么解释:所谓的守护现成也只是相对的,没有什么神奇的地方,也就是一个线程摆了。 就好比是一个大官,旁边跟着一个报表,防止大官摔着了什么的。

       特点:一旦所有用户线程都结束运行,守护线程会随JVM一起结束工作

       应用:数据库连接池中的监测线程

              JVM虚拟机启动后的监测线程

       最常见的是:垃圾回收线程

 

如何设置?

 举个例子:

看代码:

 1 import java.io.File;
 2 import java.io.FileOutputStream;
 3 import java.io.OutputStream;
 4 import java.util.Scanner;
 5 
 6 
 7 class DeamonThread implements Runnable{
 8 
 9     @Override
10     public void run() {
11         System.out.println("进入守护线程"+Thread.currentThread().getName());
12         
13         try {
14             writeToFile();
15         } catch (Exception e) {
16             e.printStackTrace();
17         }
18         System.out.println("退出守护线程"+Thread.currentThread().getName());
19     }
20 
21     private void writeToFile() throws Exception{
22         File filename=new File("d:"+File.separator+"daemon.txt");
23         OutputStream os=new FileOutputStream(filename, true);
24         int count=0;
25         while(count<999){
26             os.write(("\r\nword"+count).getBytes());
27             System.out.println("守护线程"+Thread.currentThread().getName()+
28                     "向文件中写入word"+count++);
29             Thread.sleep(1000);
30             
31         }
32     }
33     
34     
35 }
36 
37 public class DeamonThreadDemo {
38 
39     /**
40      * @param args
41      */
42     public static void main(String[] args) {
43         System.out.println("进入线程"+Thread.currentThread().getName());
44         DeamonThread d=new DeamonThread();
45         Thread t=new Thread(d);
46         //手工暂停
47         t.setDaemon(true);
48         t.start();
49         
50         Scanner sc=new Scanner(System.in);
51         sc.next();
52         
53         System.out.println("退出线程"+Thread.currentThread().getName());
54     }
55 
56 }

 

运行后的控制台显示:

 

进入线程main
进入守护线程Thread-0
守护线程Thread-0向文件中写入word0
守护线程Thread-0向文件中写入word1
守护线程Thread-0向文件中写入word2....

(一直走到999,知道你在控制台用键盘输入任意字符等,就会变成下面)

退出线程main

 

注意事项:

SetDaemon(true)必须是在start()方法之前调用,否则会抛出IllegalThreadStateException异常

在守护线程中产生的新线程也是守护线程

不是所有的任务都可以分配给守护线程来执行,比如读写操作或者计算逻辑

 

 

使用jstack生成线程快照?

命令行工具,界面化工具

作用:生成JVM当前时刻线程的快照

目的:帮助定位程序问题出现的原因,如长时间停顿、CUP占用率过高等

 

 jstack如何使用这里就不详细说了。