本文要求基本了解JAVA編程知識。
Windows 7/EditPlus
源文件
進程是程序在處理機中的一次運行。一個進程既包括其所要執行的指令,也包括了執行指令所需的系統資源,不同進程所占用的系統資源相對獨立。所以進程是重量級的任務,它們之間的通信和轉換都需要操作系統付出較大的開銷。
線程是進程中的一個實體,是被系統獨立調度和分派的基本單位。線程自己基本上不擁有系統資源,但它可以與同屬一個進程的其他線程共享進程所擁有的全部資源。所以線程是輕量級的任務,它們之間的通信和轉換只需要較小的系統開銷。
Java支持多線程編程,因此用Java編寫的應用程序可以同時執行多個任務。Java的多線程機制使用起來非常方便,用戶只需關注程序細節的實現,而不用擔心后臺的多任務系統。
Java語言里,線程表現為線程類。Thread線程類封裝了所有需要的線程操作控制。在設計程序時,必須很清晰地區分開線程對象和運行線程,可以將線程對象看作是運行線程的控制面板。在線程對象里有很多方法來控制一個線程是否運行,睡眠,掛起或停止。線程類是控制線程行為的唯一的手段。一旦一個Java程序啟動后,就已經有一個線程在運行。可通過調用Thread.currentThread方法來查看當前運行的是哪一個線程。
線程創建的兩種方法JAVA中創建線程可以通過繼承Thread類和實現Runnable接口來創建一個線程。Runnable方式可以避免Thread 方式由于JAVA單繼承特性帶來的缺陷。Runnable的代碼可以被多個線程(Thread實例)共享,適合于多個線程處理同一資源的情況。
class MyThread extends Thread{ ..... @Override public void run(){ }}MyThread mt=new MyThread();mt.start();class MyThread implements Runnable{ .... @Override public void run(){ }}MyThread mt=new MyThread();Thread td=new Thread(mt);sd.start();Thread&Runnable分別模擬賣火車票class MyThread extends Thread{ PRivate int ticketsCont=5; //一共有5張火車票 private String name; //窗口, 也即是線程的名字 public MyThread(String name){ this.name=name; } @Override public void run(){ while(ticketsCont>0){ ticketsCont--; //如果還有票,就賣掉一張票 System.out.println(name+"賣掉了1張票,剩余票數為:"+ticketsCont); } }}public class TicketsThread{ public static void main(String args[]){ //創建三個線程,模擬三個窗口賣票 MyThread mt1=new MyThread("窗口1"); MyThread mt2=new MyThread("窗口2"); MyThread mt3=new MyThread("窗口3"); //啟動三個線程,也即是窗口,開始賣票 mt1.start(); mt2.start(); mt3.start(); }}class MyThread2 implements Runnable{ private int ticketsCont=1000; //一共有5張火車票 @Override public void run(){ while(true){ synchronized(this){ if(ticketsCont<=0){ break; } ticketsCont--; //如果還有票,就賣掉一張票 System.out.println(Thread.currentThread().getName()+"賣掉了1張票,剩余票數為:"+ticketsCont); /*try{ Thread.sleep(50); //通過阻塞程序來查看效果 } catch(Exception e){ System.out.println(e); }*/ } } } /*@Override //不加同步鎖 public void run(){ while(ticketsCont>0){ ticketsCont--; //如果還有票,就賣掉一張票 System.out.println(Thread.currentThread().getName()+"賣掉了1張票,剩余票數為:"+ticketsCont); } }*/}public class TicketsRunnable{ public static void main(String args[]){ MyThread2 mt=new MyThread2(); //創建三個線程來模擬三個售票窗口 Thread th1=new Thread(mt,"窗口1"); Thread th2=new Thread(mt,"窗口2"); Thread th3=new Thread(mt,"窗口3"); //啟動三個線程,也即是三個窗口,開始賣票 th1.start(); th2.start(); th3.start(); }}線程的生命周期

場景:一個主線程,一個守護線程,守護線程會在很長一段時間內向本地文件中寫入數據,主線程進入阻塞狀態等待用戶的輸入,一旦確認了用戶的輸入阻塞就會解除掉,主線程繼續運行直到結束,守護線程也會隨虛擬機一同結束。
import java.io.*;import java.util.Scanner;class Daemon implements Runnable{ @Override public void run(){ System.out.println("進入守護線程"); try{ writeToFile(); } catch(Exception e){ e.printStackTrace(); } System.out.println("退出守護線程"); } private void writeToFile() throws Exception{ File filename=new File("F:/慕課網(imooc)/細說多線程之Thread VS Runnable/daemon.txt"); OutputStream os=new FileOutputStream(filename,true); int count=0; while(count<999){ os.write(("/r/nWord"+count).getBytes()); System.out.println("守護線程"+Thread.currentThread().getName()+"向文件中寫入word"+count++); Thread.sleep(1000); } }}public class DaemonThreadDemo{ public static void main(String args[]){ System.out.println("進入主線程"+Thread.currentThread().getName()); Daemon daemonThread=new Daemon(); Thread thread =new Thread(daemonThread); thread.setDaemon(true); thread.start(); Scanner sc=new Scanner(System.in); sc.next(); System.out.println("退出主線程"+Thread.currentThread().getName()); }}測試結果

jstack工具到jdk安裝目錄bin文件夾下。jstack能生成JVM當前時刻線程的快照(threaddump, 即當前進程中所有線程的信息)。幫助定位程序問題出現的原因,如長時間停頓、CPU占用率過高等。
使用方法
jstack [-l] <pid> : [-l]可有可無,表示關于鎖的二位信息;<pid>表示進程ID。

建議使用Runnable這種方式創建線程。 程序中的同一資源指的是同一個Runnable對象。安全的賣票程序中需要加入同步synchronized。
如以上文章或鏈接對你有幫助的話,別忘了在文章結尾處輕輕點擊一下 “還不錯”按鈕或到頁面右下角點擊 “贊一個” 按鈕哦。你也可以點擊頁面右邊“分享”懸浮按鈕哦,讓更多的人閱讀這篇文章。
作者:Li-Cheng出處: http://m.survivalescaperooms.com/Li-Cheng/p/4332179.html由于本人水平有限,文章在表述和代碼方面如有不妥之處,歡迎批評指正。留下你的腳印,歡迎評論哦。你也可以關注我,一起學習哦!新聞熱點
疑難解答