1. 程式人生 > >Java之多執行緒(二)

Java之多執行緒(二)

一.多執行緒的兩種實現方式對比
第一種方式:       1)自定義類MyThread類,繼承自Thread類       2)重寫Thread類中的run()方法       3)建立MyThread類物件,分別去啟動執行緒注意:      1)啟動執行緒的時候,為什麼不使用run()方法?         run()不能作為啟動執行緒的方法,因為該方法的呼叫相當於呼叫一個普通方法,並不會出現執行緒的執行的一種隨機性!      2)啟動執行緒用的start()方法,start方法的執行,通過Jvm呼叫run()方法.         一個執行緒不要連續啟動,會出現非法執行緒狀態異常!第二種方式:      1)自定義一個類;MyRunnable實現Runnable介面      2)實現介面的run()方法      3)建立MyRunnable類物件,建立Thread類物件,將MyRunnable類物件作為引數進行傳遞,分別啟動執行緒.問題:
既然有了第一種實現方式,為什麼要出現第二種實現方式呢?第二種方式優於第一種方式的好處:       1)避免了Java單繼承的一種侷限性       2)更符合Java面向物件的一種設計原則:面向介面程式設計          將程式碼的實現和資源物件(MyRunnable)有效的分離開來(資料分離原則!)
二.執行緒的生命週期
執行緒從開始建立的時候,一直到執行緒的執行,最終到執行緒的終止!新建執行緒:此時此刻該執行緒沒有執行資格,沒有執行權執行緒就緒:執行緒有執行資格了,但是沒有執行權      在執行執行緒之前,執行緒還可能會阻塞執行緒執行:執行緒有執行資格並且有執行權執行緒死亡:執行緒執行完畢,會被垃圾回收執行緒中的垃圾回收器及時從記憶體中釋放掉.
三.多執行緒的同步機制
問題引入:       需求:某電影院出售某些電影的票(復聯3,....),有三個視窗同時進行售票(100張票),請您設計一個程式,模擬電影院售票;為了模擬更真實的場景,加入延遲操作(讓我們執行緒睡100毫秒)
public class SellTicket implements Runnable {
	
	//定義100張票
	private int tickets = 100 ;

	@Override
	public void run() {
		
		
		while(true) {
			try {
				//t1睡 t2睡
				Thread.sleep(100); //t2睡
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			if(tickets>0) {
				//t1,t2,t3 三個執行緒執行run裡面程式碼
				//為了模擬更真實的場景(網路售票有延遲的),稍作休息
				
				System.out.println(Thread.currentThread().getName()
						+"正在出售第"+(tickets--)+"張票");//0
			}
		}
	}

}

public static void main(String[] args) {
		
		//建立資源類物件(共享資源類/目標物件)
		SellTicket st = new SellTicket() ;
		
		//建立執行緒類物件
		Thread t1 = new Thread(st, "視窗1") ;
		Thread t2 = new Thread(st ,"視窗2") ;
		Thread t3 = new Thread(st, "視窗3") ;
		
		//啟動執行緒
		t1.start();
		t2.start();
		t3.start();
	}
程式的設計是好的,但是結果有一些問題:
    1)同一張票被賣了多次
              CPU的執行有一個特點(具有原子性操作:最簡單最基本的操作)
    2)出現了0或者負票
             (延遲操作+執行緒的執行隨機性)1.通過剛才的這個程式,有安全問題(同票還是負票)
  
  如何解決多執行緒的安全問題?
       校驗一個多執行緒程式是否有安全問題的隱患的前提條件:
      1)當前程式是否是多執行緒環境
      2)是否有共享資料
      3)是否有多條語句對共享資料進行操作
2.解決方案:就是將多條語句對共享資料操作的程式碼,用一個程式碼包起來---->同步程式碼塊(理解為門的開和關)   格式:
     synchronized(鎖物件){
       針對多條語句對共享資料操作程式碼;
     }

  注意:
      鎖物件:一定要同一個鎖(每個執行緒只能使用同一把鎖)
      鎖物件:任何的Java類(引用型別)  
public class SellTicket implements Runnable {
	
	//定義100張票
	private int tickets = 100 ;
	
	private Object obj = new Object() ;

	@Override
	public void run() {
		while(true) {
			synchronized(obj) { //門的開和關
				if(tickets>0) {
					try {
						Thread.sleep(100); 
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()
							+"正在出售第"+(tickets--)+"張票");
				}
			}
			
		}
	}

}
  3. 如果一個方法一進來就是同步程式碼塊,那麼可不可以將同步放到方法來進行宣告呢? 可以    同步方法 :裡面鎖物件是誰?    (1)非靜態的同步方法:  鎖物件:this
private synchronized  void sellTicket() {
			if(tickets>0) {
				try {
					Thread.sleep(100); 
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()
						+"正在出售第"+(tickets--)+"張票");
			}
		}
(2)靜態的同步方法:和反射有關 (靜態同步方法的鎖物件:類名.class)
private synchronized static  void sellTicket() {
		if(tickets>0) {
			try {
				Thread.sleep(100); 
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()
					+"正在出售第"+(tickets--)+"張票");
		}
	}
4.執行緒安全的類
StringBuffer sb = new StringBuffer() ;
		Vector<String> v = new Vector<String>() ;
		Hashtable<String, String> hm = new Hashtable<String,String>() ;
Vector<String>它是執行緒安全的類,還是不習慣使用這個集合,         使用ArrayList集合:執行緒不安全的類,通過Collections集合中的synchronizedList()變成執行緒安全的類public static <T> List<T> synchronizedList(List<T> list):返回指定列表支援的同步(執行緒安全的)列表
List<String> array = new ArrayList(); //執行緒不安全的類
		
		//public static <T> List<T> synchronizedList(List<T> list)
		//返回指定列表支援的同步(執行緒安全的)列表
		List list = Collections.synchronizedList(array) ; //執行緒安全的方法

相關推薦

Java執行()

一.多執行緒的兩種實現方式對比第一種方式:       1)自定義類MyThread類,繼承自Thread類       2)重寫Thread類中的run()方法       3)建立MyThread類物件,分別去啟動執行緒注意:      1)啟動執行緒的時候,為什麼不使用

Java基礎執行

        /* 這是flag=1這個執行緒 */         if (flag == 1) {             synchronized (o1) {                 /* 使用synchronized關鍵字把物件01鎖定了 */                 try {

Java執行安全(屌絲版,兩大解決思路,要麼不去競爭(開闢執行副本)、要麼有順序的競爭資源(用鎖規定執行秩序))

0、多執行緒安全,如果多個執行緒操作一個變數,每次都能達到預期的結果,那麼說明當前這個類起碼是執行緒安全的,我這白話的,可能有點噁心。   1、看看牛人是怎麼說的,為什麼多執行緒併發是不安全的? 在作業系統中,執行緒是不再擁有資源的,程序是擁有資源的。而執行緒是由程序建立的

Java執行的常用操作

執行緒命名與取得 在Thread類中提供有如下的執行緒名稱方法: 在Thread類中還提供有一個方法取得當前執行緒物件: public static native Thread currentThread(); 範例:設定和取得執行緒的名稱 class M

JAVA執行概念及其幾種實現方法優劣分析

1. 多執行緒 程式:指令集,靜態的概念 程序:作業系統調動程式,是程式的一次動態執行過程,動態的概念 執行緒:在程序內的多條執行路徑 Ps:單核的話程序都是虛擬模擬出來的,多核處理器才可以執行真正的多執行緒 單核通過CPU排程時間片實現虛擬模擬的多執行緒,比如執行main函式和GC在底層就是多執行

Java執行易範錯誤

public class mainTestImpl { /* * 任何執行緒一般具有五種狀態,即建立、就緒、執行、阻塞、終止 執行緒 呼叫stop()方法時或run()方法執行 * 結束後,執行緒即處於死亡狀態。 處於死亡狀態的執行緒不具有繼續執行的能力。

Java執行執行

多執行緒 執行緒:執行緒是程序中的一個執行單元,負責當前程序中程式的執行,一個程序中至少一個執行緒(main),但是可以有多個執行緒的,則這個程式稱為多執行緒程式。每一個執行緒執行不同的任務,多執行緒程式並不能提高程式的執行速度,可以提高程式的執行效率。 CPU處理可以分為

java基礎-JAVA執行

------<a href="http://www.itheima.com" target="blank">Java培訓、Android培訓、iOS培訓、.Net培訓</a>、期待與您交流! ------- 要想了解執行緒,先了解程序的概念程序: 程

Java執行記憶體可見性_2(synchronized可見性原理)

可見性:要實現共享變數的可見性,必須保證2點:1.執行緒修改後的共享變數值能夠及時從工作記憶體重新整理到主記憶體中。2.其他執行緒能夠及時把共享變數的最新值從主記憶體更新到自己的工作記憶體中。 以下的記錄都是來源於慕課網-細說java多執行緒之記憶體可見性 Java語言層

Java執行面試題

很多核心Java面試題來源於多執行緒(Multi-Threading)和集合框架(Collections Framework),理解核心執行緒概念時,嫻熟的實際經驗是必需的。這篇文章收集了 Java 執行緒方面一些典型的問題,這些問題經常被高階工程師所問到。 0.Java

java執行中Thread類和Runnable介面使用方法

java提供了兩種執行緒方式,一種是繼承java.lang包下的Thread類,覆寫Thread類的run()方法,在run()方法中實現執行線上程上的程式碼!第二種是實現Runnable介面建立多執行

黑馬程式設計師執行

---------------------- Windows Phone 7手機開發、.Net培訓、期待與您交流! ---------------------- Thread類幾個重要的方法: Start():啟動執行緒; Sleep(int):靜態方法,暫停當前執行緒指定

java執行

1、執行緒概述 幾乎所有的作業系統都支援同時執行多個任務,一個任務通常就是一個程式,每個執行中的程式就是一個程序。當一個程式執行時,內部可能包含了多個順序執行流,每個順序執行流就是一個執行緒。   2、執行緒與程序 程序概述: 幾乎所有的作業系統都支援程序的概念,所有執行中的任務通常對應一個程

Java執行(一)

一,前言 ​ 今天總結一些關於執行緒方面的知識,說到執行緒可謂是無人不知,畢竟這東西不管是在工作開發中,還是實際生活中都時時存在著。關於執行緒方面的內容非常多,從簡單的單執行緒,多執行緒,執行緒安全以及到高併發等等,當然也包括資訊通訊。 ​ 當然這次從執行緒的基本開始,後面也會慢慢的補充執行緒的高階使用,這也

java學習第十執行死鎖和併發

package MoreThreadLearn; /* 兩個儲戶到銀行存錢,每個人存了三次,一次100元 1、描述銀行 2、描述儲戶業務 分析多執行緒是否存在安全隱患? 1、執行緒任務中是否有共享的資料 2、是否多條操作共享資料的程式碼 */ public

黑馬程式設計師——java基礎拾遺執行執行同步、執行通訊

執行緒安全的概念:當多個執行緒同時執行一段程式碼時,如果結果和單執行緒執行時一致,而且其他變數也和預期的一致,說明是這段程式碼是執行緒安全的。但是,多執行緒執行的過程中會出現單執行緒時候不會出現的問題,大多出現在多個執行緒同時操作全域性變數或者靜態變數的時候。當出現這種

java面試/筆試題目執行及鎖 (持續更新中)

前言:這一模組可以參照徐劉根大佬的部落格。 一.執行緒和程序的概念、並行和併發的概念 1.程序:是計算機中的程式關於某資料集合上的一次執行活動,是系統 進行資源分配和排程的基本單位,是作業系統結構的基礎。程式是指令、資料及其組織形式的描述,程序是程式的實體。 2.執行緒:是程式執行流的

java執行系列翻譯java併發/執行教程

原文地址:http://tutorials.jenkov.com/java-concurrency/index.html 以前計算機都是單核,同時只能執行一個程式。之後出現了多重任務處理,這意味著計算機同時可以處理多個程式(又名任務或流程)。但這不是真正的“同時執行”,只是單個CPU被多個程式共

JAVA複習執行

java中多執行緒同步是什麼? 在多執行緒程式下,同步能控制對共享資源的訪問。如果沒有同步,當一個java縣城在修改一個共享變數時,另外一個執行緒正在使用或者更新同一個變數,這樣容易導致程式出現錯誤。 解釋實現多執行緒的幾種方法?區別是什麼? Java執行緒可以實現Runnable介面或

Java基礎執行及併發庫

實際上關於多執行緒的基礎知識,前面自己已經總結過一部分,但是每一個階段對於同樣知識點的學習側重點是不一樣的,前面的Java基礎總結八之多執行緒(一)和 Java基礎總結九之多執行緒(二)是對JDK5以前多執行緒相關基礎知識的一個簡單總結,今天本文將偏重於JDK5提供的併發庫進行學習總結。 首先,