一.線程概述

1.進程和線程的概念

進程:進程是操做系統結構的基礎;是一次程序的執行;是一個程序及其數據在處理機上順序執行時所發生的活動;是程序在一個數據集合上運行的過程,它是系統進行資源分配和調度的一個獨立單位;進程是受操做系統管理的基本運行單元。java

線程:能夠理解成是在進程中獨立運行的子任務;使用多線程也就是在使用異步。線程分爲兩種一種是用戶線程,一種是守護線程;守護線程是一種特殊的線程,當進程中不存在非守護線程了,則守護線程自動銷燬(垃圾回收線程),setDaemon(true)設置線程爲守護線程。多線程

2.建立線程的方式

  • 繼承Thread類
package chapter1.create;

public class MyThread extends Thread{
	
	@Override
	public void run() {
		super.run();
		System.out.println("MyThread");
	}

}

 

package chapter1.create;

public class Run {
    
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
        System.out.println("end!");
    }

}

運行結果以下:異步

end!
MyThreadide

線程是一個子任務,CUP以不肯定的方式,或者說是隨機的時間來調用線程中的run方法,因此就會出現先打印end!,再打印MyThread了。this

  • 實現Runnable接口
package chapter1.create;

public class MyRunnable implements Runnable{

	@Override
	public void run() {
		System.out.println("運行中...");
	}

}

 

package chapter1.create;

public class Run {
	
	public static void main(String[] args) {
		MyRunnable myRunnable = new MyRunnable();
		Thread thread = new Thread(myRunnable);
		thread.start();
		System.out.println("運行結束");
	}

}

 運行結果:spa

運行結束
運行中...
Thread.java類也實現了Runnable接口,也就意味着Thread(myRunnable)能夠傳入一個Thread類的對象,這樣作能夠將一個Thread對象中的run方法交由其餘的線程進行調用。操作系統

使用繼承Thread類的方式建立線程時,最大的侷限就是不支持多繼承。線程

3.經常使用方法介紹

  • currentThread()方法可返回代碼段正在被哪一個線程調用的信息。
package chapter1.create;

public class MehthodCurrentThreadTest {
   
    static class CountOperate extends Thread{
        public CountOperate() {
            System.out.println("CountOperate init----begin");
            System.out.println("Thread.currentThread().getName()="+Thread.currentThread().getName());
            System.out.println("this.getName()="+this.getName());
            System.out.println("CountOperate init----end");
        }
        
        @Override
        public void run() {
            super.run();
            System.out.println("run----begin");
            System.out.println("Thread.currentThread().getName()="+Thread.currentThread().getName());
            System.out.println("this.getName()="+this.getName());
            System.out.println("run----end");
        }
    }
    
    public static void main(String[] args) {
        CountOperate countOperate = new CountOperate();
        Thread t = new Thread(countOperate);
        t.setName("A");
        t.start();
    }
}

運行結果:code

CountOperate init----begin
Thread.currentThread().getName()=main
this.getName()=Thread-0
CountOperate init----end
run----begin
Thread.currentThread().getName()=A
this.getName()=Thread-0
run----end對象

  • isAlive()判斷當前的線程是否處於活動狀態,活動狀態就是線程已經啓動且還沒有終止。
  • sleep()是在指定的毫秒數內讓當前"正在執行的線程"休眠(暫停執行),這個"正在執行的線程"是指this.currentThread()返回的線程。
  • getId()取得線程的惟一標識。
  • yield()方法的做用是放棄當前的CPU資源,將它讓給其餘的任務去佔用CPU執行時間。但放棄的時間不肯定,有可能剛剛放棄,立刻有得到CPU時間片。
  • suspend():暫停,已廢棄。會有獨佔和不一樣步的問題。
  • resume():恢復,已廢棄;會有獨佔和不一樣步的問題。

 4.中止線程

判斷線程是否爲中斷狀態的方法:

  • interrupted():當前線程是否已是中斷狀態,當前線程指運行interrupted()方法的線程,執行後具備將狀態標誌清除爲false的功能;
    • public static boolean interrupted() {
            return currentThread().isInterrupted(true);
      }
  • isInterrupted():線程對象是否已是中斷狀態,但不清除狀態標誌。

中止線程的方法:

  • 使用interrupt方法中斷線程,但方法並無中止線程,只是將狀態標誌爲中斷,調用isInterrupted()將返回true。
package chapter1.create.threadinterrupt;

public class MyThread extends Thread{
	
	@Override
	public void run() {
		super.run();
		for(int i=0;i<500000;i++) {
			System.out.println("i="+(i+1)+"interrupted------------"+this.isInterrupted());
		}
	}

}

 

package chapter1.create.threadinterrupt;

public class Run {
	
	public static void main(String[] args) {
		try {
			MyThread myThread = new MyThread();
			myThread.start();
			Thread.sleep(2000);
			myThread.interrupt();
		} catch (Exception e) {
			System.out.println("main catch.");
			e.printStackTrace();
		}
	}

}

 運行結果:

i=499992interrupted------------true
i=499993interrupted------------true
i=499994interrupted------------true
i=499995interrupted------------true
i=499996interrupted------------true
i=499997interrupted------------true
i=499998interrupted------------true
i=499999interrupted------------true
i=500000interrupted------------true

在沉睡中中止:

package chapter1.create.threadinterrupt;

public class StopWhenSleepTest {

static class MyThread extends Thread{
		
		@Override
		public void run() {
			super.run();
			try {
				System.out.println("run begin");
				Thread.sleep(200000);
				System.out.println("run end");
			} catch (InterruptedException e) {
				System.out.println("進MyThread.java類run方法中的catch了。"+this.isInterrupted());
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		try {
			MyThread myThread = new MyThread();
			myThread.start();
			Thread.sleep(2000);
			myThread.interrupt();
		} catch (Exception e) {
			System.out.println("main catch.");
			e.printStackTrace();
		}
		System.out.println("Main end");
	}
}

 運行結果:

run begin
Main end
進MyThread.java類run方法中的catch了。false
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at chapter1.create.threadinterrupt.StopWhenSleepTest$MyThread.run(StopWhenSleepTest.java:12)

若是在sleep狀態下中止線程,會進入catch,而且清楚中止狀態值,使之成爲false。先interrupt再sleep也會進入catch,此處不作贅述。

  • 異常法
package chapter1.create.threadinterrupt;

public class StopThreadByExceptionTest {
	
	static class MyThread extends Thread{
		
		@Override
		public void run() {
			super.run();
			try {
				for(int i=0;i<500000;i++) {
					if(this.isInterrupted()) {
						System.out.println("已是中止狀態了!我要退出了");
						throw new InterruptedException();
					}
					System.out.println("i="+(i+1));
				}
			} catch (InterruptedException e) {
				System.out.println("進MyThread.java類run方法中的catch了。");
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		try {
			MyThread myThread = new MyThread();
			myThread.start();
			Thread.sleep(2000);
			myThread.interrupt();
		} catch (Exception e) {
			System.out.println("main catch.");
			e.printStackTrace();
		}
	}

}

 運行結果:
i=420003
i=420004
i=420005
i=420006
i=420007
i=420008
i=420009
i=420010
i=420011
已是中止狀態了!我要退出了
進MyThread.java類run方法中的catch了。
java.lang.InterruptedException
    at chapter1.create.threadinterrupt.StopThreadByExceptionTest$MyThread.run(StopThreadByExceptionTest.java:14)

  • 使用return中止線程:判斷this.isInterrupted()爲true,return。不過仍是建議使用「異常法」,由於在catch塊中能夠對異常的信息進行相關的處理,並且使用異常流能更好、更方便地控制程序的運行流程。
  • stop()暴力中止。該方法已經被廢棄,由於若是強制讓線程中止則有可能使一些清理性的工做得不到完成。另一個狀況就是對鎖定的對象「解鎖」,致使數據得不到同步的處理,出現數據不一致的問題。

 5.線程的優先級

setPriority(int priority):值的範圍1-10,設置線程優先級有助於幫「線程規劃器」肯定在下一次選擇哪個線程來優先執行。

  • 線程的優先級具備繼承性,好比A線程啓動B線程,則B線程的優先級與A是同樣的。
  • 線程的優先級具備必定的規則性,也就是CPU儘可能將執行資源讓個優先級較高的線程。
  • 線程的優先級具備隨機性,也就是優先級較高的線程不必定每一次都先執行。
相關文章
相關標籤/搜索