1. 程式人生 > >【自用】java多執行緒程式設計學習筆記(程式碼片段來源於網路)

【自用】java多執行緒程式設計學習筆記(程式碼片段來源於網路)

執行緒的基本概念

執行緒是在邏輯上等同於作業系統中說的程序,是程序的細分。比如我們使用同一個軟體同時對電腦進行體檢和防毒的時候,我們就是開啟了那個軟體的程序的兩個執行緒,在邏輯上這兩個執行緒是同時被cpu執行的。

執行緒的生命週期

執行緒的生命週期分為建立,就緒,執行,阻塞和死亡,當我們時候start()方法的時候就是建立一個執行緒,當這個執行緒所有資源都準備就緒,就差cpu執行的時候那麼就進入就緒佇列等待,當獲得cpu時間片的時候就處於執行週期,倘若執行緒時間片用完而任務沒有完成的話就會再次進入就緒佇列排隊等待,執行緒任務完成了之後就會被殺掉,在執行過程中被掛起就會進入阻塞佇列,在阻塞佇列中的執行緒被喚醒後就會進入就緒佇列繼續等待cpu時間片。

java中實現多執行緒的兩種方式

1.繼承Runnable介面實現多執行緒

Runnable介面的程式碼資訊如下

//  (version 10 : 54.0, no super bit)
@java.lang.FunctionalInterface
public abstract interface java.lang.Runnable {
  
  // Method descriptor #7 ()V
  public abstract void run();

}

當我們寫一個類繼承Runnable介面的時候一定要實現run方法,這個run方法就是我們使用多執行緒的時候想要做的事。

2.繼承Thread類實現多執行緒

Thread類實際上繼承了Runnable介面,也就是說我們在繼承Thread類的時候也要重寫run方法,實際上兩種方法的原理是一樣。

例項,繼承Thread類實現兩個執行緒分別列印1-100的奇數和1-100的偶數

package Thread;

class subthread1 extends Thread{
	public void run() {
		for(int i=1;i<=100;i++) {
			if(i%2 == 0) {
				System.out.println(Thread.currentThread().getName() + ":" + i);
			}
		}
	}
}
		
class subthread2 extends Thread{
	public void run() {
		for(int i=1;i<=100;i++) {
			if(i%2!=0) {
				System.out.println(Thread.currentThread().getName()+":"+i);
			}
		}
	}
}

public class TestThread {
	public static void main(String [] args) {
		subthread1 st1 = new subthread1();
		subthread2 st2 = new subthread2();
		st1.start();
		st2.start();
	}
}

執行緒死鎖的基本概念及執行緒同步

當兩個執行緒同時都握有對方所需的資源的時候,就進入了死鎖狀態,即兩個執行緒互相無限期等待。

比如下面這個程式就會產生死鎖。

package Thread;

public class TestDeadLock {
	static StringBuffer sb1 = new StringBuffer();
	static StringBuffer sb2 = new StringBuffer();
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new Thread() {
			public void run() {
				synchronized(sb1) {
					try {
						Thread.currentThread().sleep(10);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					sb1.append("A");
					synchronized(sb2) {
						sb2.append("B");
						System.out.println(sb1);
						System.out.println(sb2);
					}
				}
			}
		}.start();
		
		new Thread() {
			public void run() {
				synchronized(sb2) {
					try {
						Thread.currentThread().sleep(10);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					sb1.append("C");
					synchronized(sb1) {
						sb2.append("D");
						System.out.println(sb1);
						System.out.println(sb2);
					}
				}
			}
		}.start();
	}

}

我們通常採用執行緒同步來解決死鎖問題。

使用synchronized關鍵字標註的方法就是支援程序同步的方法,它的形參可以是任何一個物件,一個物件代表了一把鎖,也就是說同一個物件代表了同一把鎖。

如上面一段程式碼所示,synchronized也可以用大括號來單獨修飾一段程式碼。

在上面的程式碼中,執行緒1握有鎖sb1,等待sb2;執行緒2握有sb2,等待sb1。他們互相都在等在對方暫時不會放棄的資源,就產生了死鎖。

死鎖的一個解決方法

我們可以用wait(),notify()和notifyAll()三個問題來避免死鎖的產生。這三個方法都來自與Object類。

wait()方法可以將當前執行緒掛起,notify()方法喚醒阻塞佇列中優先順序最高的執行緒進入就緒佇列,notifyAll()喚醒所有阻塞佇列中的執行緒進入就緒佇列。

生產者消費者問題

package Thread;
/*
 * 生產者producer將產品交給店員clerk,然後店員將產品交給顧客customer
 */
class Clerk{
	int number ; //表示產品數量(預設訪問模式,只允許同一個包進行訪問)
	public synchronized void pro() {
		if(number >= 20) {
			//如果產品大於等於20,將生產者執行緒掛起
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		else {
			number++;
			System.out.println(Thread.currentThread().getName()+"生產了"+number+"個產品");
			notify();
		}
	}
	public synchronized void con() {
		if(number <= 0) {
			//如果產品小於等於0則將消費者執行緒掛起
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		else {
			System.out.println(Thread.currentThread().getName()+"消費了"+number+"個產品");
			number--;
			notify();
		}
	}
}

class Producer implements Runnable{
	Clerk clerk;
	public Producer(Clerk clerk) {
		this.clerk = clerk;
	}
	public void run() {
		while(true) {
			try {
				Thread.currentThread().sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			clerk.pro();
		}
	}
}

class Customer1 implements Runnable{
	Clerk clerk;
	public Customer1(Clerk clerk) {
		this.clerk = clerk;
	}
	public void run() {
		while(true) {
		try {
			Thread.currentThread().sleep(10);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		clerk.con();
		}
	}
}

public class TestProducerandcustomer {
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Clerk clerk = new Clerk();
		Producer p1 = new Producer(clerk);
		Customer1 c1 = new Customer1(clerk);
		Thread t1 = new Thread(p1);
		Thread t2 = new Thread(p1);
		Thread t3 = new Thread(c1);
		t1.setName("生產者1");
		t2.setName("生產者2");
		t3.setName("消費者1");
		t1.start();
		t2.start();
		t3.start();
	}

}

相關推薦

自用java執行程式設計學習筆記程式碼片段來源於網路

執行緒的基本概念 執行緒是在邏輯上等同於作業系統中說的程序,是程序的細分。比如我們使用同一個軟體同時對電腦進行體檢和防毒的時候,我們就是開啟了那個軟體的程序的兩個執行緒,在邏輯上這兩個執行緒是同時被cpu執行的。 執行緒的生命週期 執行緒的生命週期分為建立,就緒,執行,

專欄 - Java 執行程式設計

Java 多執行緒程式設計 Java多執行緒程式設計,是併發程式設計的一種(另一種重要的併發程式設計是多程序程式設計)。我們寫java程式一般是執行在同一個程序中的,所以可以簡單的認為:併發程式設計 = 多執行緒程式設計,讓寫作業

Java執行程式設計學習總結

  (尊重勞動成果,轉載請註明出處:https://blog.csdn.net/qq_25827845/article/details/84894463冷血之心的部落格) 系列文章: Java多執行緒程式設計學習總結(一) Java多執行緒程式設計學習總結(二) 前

Java 執行程式設計學習總結

定義篇 程序(Process)和執行緒(Thread) 怎樣實現多工處理(Multitasking)? 多工處理是同時執行多個任務的過程。我們使用多工處理來利用 CPU。可通過兩種方式實現多工處理: · 基於程序的多工 (多重處理) · 基於執行緒的多工處理

新聞本人新書《Java執行程式設計實戰指南核心篇》已出版上市

豆瓣主頁 購買連結 試讀下載 (待補充) 原始碼下載 內容簡介 隨著現代處理器的生產工藝從提升處理器主頻頻率轉向多核化,即在一塊晶片上整合多個處理器核心(Core),多核處理器(Multicore Proc

Java執行-同步集合和併發集合

同步集合可以簡單地理解為通過synchronized來實現同步的集合。如果有多個執行緒呼叫同步集合的方法,它們將會序列執行。 arrayList和vector、stack Vector是執行緒安全的,原始碼中有很多的synchronized可以看出,而

Java執行-CyclicBarrier 柵欄

CyclicBarrier 類介紹 CyclicBarrier是一個同步工具類,它允許一組執行緒在到達某個柵欄點(common barrier point)互相等待,發生阻塞,直到最後一個執行緒到達柵欄點,柵欄才會開啟,處於阻塞狀態的執行緒恢復繼續執行.它

Java執行程式設計總結筆記——03概念與原理

作業系統中執行緒和程序的概念 現在的作業系統是多工作業系統。多執行緒是實現多工的一種方式。 程序是指一個記憶體中執行的應用程式,每個程序都有自己獨立的一塊記憶體空間,一個程序中可以啟動多個執行緒。比如在Windows系統中,一個執行的exe就是一個程序。執行

Java執行程式設計總結筆記——02執行基礎知識

讀解Thread類API 構造方法摘要 Thread(Runnable target) 分配新的 Thread 物件。 Thread(String name) 分配新的 Thread 物件。 方法摘要 static Thread cur

Java執行程式設計總結筆記——01 Java語言的執行

GUI應用程式 幾乎所有的GUI應用程式都會用多執行緒。舉例來說加入現在有人在用word編輯一個比較大的文字檔案剛剛才做過單字“查詢”操作,當word進行查詢時,螢幕上會出現“停止查詢按鈕”,使用者可以隨時停止查詢。這個功能其實就用到了多執行緒。 (1)執行

Java執行程式設計學習

擴充套件Java.lang.Thread類 實現java.lang.Runnable介面 Thread和Runnable的區別 執行緒狀態轉換 執行緒排程 程序:每個程序都有獨立的程式碼和資料空間(程序上下文),程序間的切換比較大,一個進行包含1-n

Java執行程式設計實戰指南核心篇讀書筆記

博主準備惡補一番Java高併發程式設計相關知識,接下來將閱讀該書,並且進行比較詳細的總結,好記性不如爛筆頭,加油。Java多執行緒程式設計實戰指南(核心篇)讀書筆記(四),主要記錄該書第七章和第八章的基

Java執行程式設計學習與實踐

怎麼樣才算得上熟悉多執行緒程式設計?第一,明白程序和執行緒的基本概念第二,明白保護執行緒安全的基本方法有哪些第三,明白這些執行緒安全的方法,包括互斥鎖,自旋鎖,無鎖程式設計的適用的業務場景是什麼?從OS和硬體角度說說原理是怎麼樣的?開銷在哪裡?第四,能在現場藉助cas操作,風

Java執行面試題整理BATJ都愛問

今天給大家總結一下,面試中出鏡率很高的幾個多執行緒面試題,希望對大家學習和麵試都能有所幫助。備註:文中的程式碼自己實現一遍的話效果會更佳哦! 一、面試中關於 synchronized 關鍵字的 5 連擊 1.1 說一說自己對於 synchronized 關鍵字的瞭解 synchroniz

執行程式設計學習筆記——執行同步

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; //引入執行緒 using System.Diagnostics; namesp

Java執行程式設計核心技術第一章(執行技能suspend,resume,yield)

1.8 暫停執行緒      在多執行緒中,suspend是暫停執行緒,resume是恢復執行緒的執行.  1.8.1suspend方法和resume方法的使用 public class MyThread extends Thread { private lon

Java執行程式設計核心技術第一章(執行技能 執行的優先順序)

1.8 執行緒的優先順序  在作業系統中,執行緒可以劃分優先順序,優先順序較高的執行緒得到的cpu的資源較多,也就是cpu優先執行優先順序較高的執行緒物件中的任務.  在Java中,執行緒優先順序分為1~10個等級,如果小於1大於10,則JDK丟擲異常,原始碼如下:

java執行程式設計歷史演變截止到jdk8

最近看了咕泡學視訊教程,這裡算是做一個記錄。 一、JDK1.5之前時代 建立執行緒的方式 繼承thread package study.java5; /** * @Auther: zhw * @D

Java程式設計Java執行的實現

多執行緒 程式:是一個指令的集合。 程序:正在執行中的程式,是一個靜態的概念。 執行緒:是程序中的一個單一的連續控制流程,執行緒又本稱為輕量級程序。 一個程序可擁有多個並行的執行緒,一個程序中的執行緒共享相同的記憶體單元,記憶體地址空間,可以訪問相同的變數和物件,而且他們從

Java執行程式設計核心技術第四章 Lock的使用

使用ReentrantLock類 Lock lock = new ReentrantLock(); lock.lock(); //同步的程式碼段 ... lock.unlock(); Condition用法:await(), signal()方法呼叫之前需要呼叫lock.loc