欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java?synchornized與ReentrantLock處理并發(fā)出現(xiàn)的錯誤

 更新時間:2023年01月05日 08:45:31   作者:欲無緣  
synchronized機制提供了對每個對象相關的隱式監(jiān)視器鎖,并強制所有鎖的獲取和釋放都必須在同一個塊結構中。當獲取了多個鎖時,必須以相反的順序釋放。即synchronized對于鎖的釋放是隱式的

什么是并發(fā)錯誤

多個線程共享操作同一個對象的時候,線程體當中連續(xù)的多行操作未必能夠連續(xù)執(zhí)行 很可能操作只完成了一部分,時間片突然耗盡,此時,另一個線程搶到時間片,直接拿走并訪問了操作不完整的數(shù)據(jù)(操作不完整的數(shù)據(jù),從邏輯上講是錯誤數(shù)據(jù))。

并發(fā)錯誤是如何產(chǎn)生的

根本原因: 多個線程共享操作同一份數(shù)據(jù)

直接原因: 線程體當中連續(xù)的多行語句,未必能夠連續(xù)執(zhí)行,很可能操作只完成了一半 時間片突然耗盡。

此時另一個線程剛好搶到時間片,直接拿走了操作不完整的數(shù)據(jù) - 錯誤數(shù)據(jù)。

導火索: 時間片突然耗盡

演示并發(fā)錯誤

public class TestConcurrentError{
	public static void main(String[] args){
		Student stu = new Student("張朝偉","先生");
		PrintThread pt = new PrintThread(stu);
		ChangeThread ct = new ChangeThread(stu);
		pt.start();
		ct.start();
	}
}
class PrintThread extends Thread{
	Student stu;
	public PrintThread(Student stu){
		this.stu = stu;
	}
	@Override
	public void run(){
		while(true){
			System.out.println(stu);
		}
	}
}
class ChangeThread extends Thread{
	Student stu;
	public ChangeThread(Student stu){
		this.stu = stu;
	}
	@Override
	public void run(){
		boolean isOkay = true;
		while(true){
				if(isOkay){ 
					stu.name = "張曼玉";
					stu.gender = "女士";
				}else{ 
					stu.name = "梁朝偉";
					stu.gender = "先生";
				}
				isOkay = !isOkay;
		}
	}
}
class Student{
	String name;
	String gender;//性別
	public Student(String name,String gender){
		this.name = name;
		this.gender = gender;
	}
	@Override
	public String toString(){
		return name + " : " + gender;
	}
}

我們看運行結果發(fā)現(xiàn)一個非常嚴重的問題

我們的代碼從來沒有寫過將梁朝偉賦值為女士,也沒有寫過將張曼玉賦值為女士我們的程序為什么會出現(xiàn)這樣的情況 ?

線程體當中連續(xù)的多行操作未必能夠連續(xù)執(zhí)行 假如我們將stu的名字賦值為梁朝偉,此時CPU時間片耗盡了,另一個打印的線程搶到時間片的情況下 就會將原來的正確的值改為錯誤的數(shù)據(jù) 從而產(chǎn)生并發(fā)錯誤。

如何解決并發(fā)錯誤

要想解決并發(fā)錯誤加鎖是必須的

使用synchornized解決并發(fā)錯誤

synchronize語法級別的加鎖 也叫? 互斥鎖=互斥標記=鎖標記=鎖旗標=監(jiān)視器= Monitor

synchornized修飾代碼塊

synchronized(臨界資源){
	//需要連續(xù)執(zhí)行的操作
}

synchornized修飾整個方法

public synchronized void add(){
}
//等價于
public void add(){
	synchronized(){
	}
}

注意:即便synchronized加在方法上,其實還是對對象進行加鎖,而且鎖的是調用方法的那個對象Java世界里只有每個對象才有鎖標記,所以加鎖只能對對象加鎖。

public class TestConcurrentError{
	public static void main(String[] args){
		Student stu = new Student("張朝偉","先生");
		PrintThread pt = new PrintThread(stu);
		ChangeThread ct = new ChangeThread(stu);
		pt.start();
		ct.start();
	}
}
//1st.用于打印顯示數(shù)據(jù)的線程 
class PrintThread extends Thread{
	Student stu;
	public PrintThread(Student stu){
		this.stu = stu;
	}
	@Override
	public void run(){
		while(true){
			synchronized(stu){//我們要對一組連續(xù)的操作加鎖 不要對所有操作加鎖
							  //我們去廁所 只是鎖一次上廁所的過程 不要一輩子死在廁所里
				System.out.println(stu);
			}
		}
	}
}
class ChangeThread extends Thread{
	Student stu;
	public ChangeThread(Student stu){
		this.stu = stu;
	}
	@Override
	public void run(){
		boolean isOkay = true;
		while(true){
			synchronized(stu){
				if(isOkay){ 
					stu.name = "張曼玉";
					stu.gender = "女士";
				}else{ 
					stu.name = "梁朝偉";
					stu.gender = "先生";
				}
				isOkay = !isOkay;
			}
		}
	}
}
class Student{
	String name;
	String gender;
	public Student(String name,String gender){
		this.name = name;
		this.gender = gender;
	}
	@Override
	public String toString(){
		return name + " : " + gender;
	}
}

使用ReentrantLock解決并發(fā)錯誤

java.util.concurrent.locks.ReentrantLock(jdk 5.0開始):java包的工具包的并發(fā)包的 可重入鎖

ReentrantLock :lock(加鎖) unlock(解鎖):放在finally{}中

ReentrantLock可以在構造方法中傳公平鎖和非公平鎖(公平與否針對第一個先來的線程而言)

公平鎖:new Reetrantlock(true);

  • JDK6.0之前這個Lock的機制比synchronized效率高很多 JDK6.0開始
  • 重新對synchronized修改了底層實現(xiàn),加入了一堆新的概念 (偏向鎖 輕量級鎖 鎖的自旋機制) 從JDK6.0開始 synchronized 跟 Lock性能上不相上下
import java.util.concurrent.locks.*;
public class TestConcurrentErrorWithLock{
	public static void main(String[] args){
		Lock lock = new ReentrantLock();
		Student stu = new Student("張朝偉","先生");
		PrintThread pt = new PrintThread(stu,lock);
		ChangeThread ct = new ChangeThread(stu,lock);
		pt.start();
		ct.start();
	}
}
//1st.用于打印顯示數(shù)據(jù)的線程
class PrintThread extends Thread{
	Student stu;
	Lock lock;
	public PrintThread(Student stu,Lock lock){
		this.stu = stu;
		this.lock = lock;
	}
	@Override
	public void run(){
		while(true){
			lock.lock();//鎖 既是一個名詞 又是一個動詞
			try{
			//synchronized(stu){//我們要對一組連續(xù)的操作加鎖 不要對所有操作加鎖
							  //我們去廁所 只是鎖一次上廁所的過程 不要一輩子死在廁所里
				System.out.println(stu);
			//}
			}finally{
				lock.unlock();
			}
		}
	}
}
class ChangeThread extends Thread{
	Student stu;
	Lock lock;
	public ChangeThread(Student stu,Lock lock){
		this.stu = stu;
		this.lock = lock;
	}
	@Override
	public void run(){
		boolean isOkay = true;
		while(true){
			//synchronized(stu){
				lock.lock();
				try{
					if(isOkay){ 
						stu.name = "張曼玉";
						stu.gender = "女士";
					}else{ 
						stu.name = "梁朝偉";
						stu.gender = "先生";
					}
					isOkay = !isOkay;
				}finally{
					lock.unlock();
				}
			//}
		}
	}
}
class Student{
	String name;
	String gender;//性別
	public Student(String name,String gender){
		this.name = name;
		this.gender = gender;
	}
	@Override
	public String toString(){
		return name + " : " + gender;
	}
}

此時已經(jīng)解決了并發(fā)錯誤

到此這篇關于Java synchornized與ReentrantLock處理并發(fā)出現(xiàn)的錯誤的文章就介紹到這了,更多相關Java synchornized與ReentrantLock內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • SpringBoot整合Web開發(fā)之文件上傳與@ControllerAdvice

    SpringBoot整合Web開發(fā)之文件上傳與@ControllerAdvice

    @ControllerAdvice注解是Spring3.2中新增的注解,學名是Controller增強器,作用是給Controller控制器添加統(tǒng)一的操作或處理。對于@ControllerAdvice,我們比較熟知的用法是結合@ExceptionHandler用于全局異常的處理,但其作用不止于此
    2022-08-08
  • Nacos作為配置中心注冊監(jiān)聽器方法

    Nacos作為配置中心注冊監(jiān)聽器方法

    本文主要討論Nacos作為配置中心時,其中配置內容發(fā)生更改時,我們的應用程序能夠做的事。一般使用監(jiān)聽器來實現(xiàn)這步操作,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2023-02-02
  • Java訪問修飾符原理及代碼解析

    Java訪問修飾符原理及代碼解析

    這篇文章主要介紹了Java訪問修飾符原理及代碼解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-06-06
  • JAVA算法起步之快速排序實例

    JAVA算法起步之快速排序實例

    這篇文章主要介紹了JAVA算法起步之快速排序實例,需要的朋友可以參考下
    2014-02-02
  • Java如何將Excel數(shù)據(jù)導入到數(shù)據(jù)庫

    Java如何將Excel數(shù)據(jù)導入到數(shù)據(jù)庫

    這篇文章主要為大家詳細介紹了Java將Excel數(shù)據(jù)導入到數(shù)據(jù)庫的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Java之Spring整合Junit

    Java之Spring整合Junit

    Java Spring框架是一個輕量級的開源框架,具有很高的凝聚力和吸引力,本篇文章帶你了解如何配置數(shù)據(jù)源、注解開發(fā)以及整合Junit
    2023-04-04
  • Java+mysql本地圖片上傳數(shù)據(jù)庫及下載示例

    Java+mysql本地圖片上傳數(shù)據(jù)庫及下載示例

    本篇文章主要介紹了Java+mysql本地圖片上傳數(shù)據(jù)庫及下載示例,具有一定的參加價值,有興趣的可以了解一下。
    2017-01-01
  • Java 線程池全面總結與詳解

    Java 線程池全面總結與詳解

    在一個應用程序中,我們需要多次使用線程,也就意味著,我們需要多次創(chuàng)建并銷毀線程。而創(chuàng)建并銷毀線程的過程勢必會消耗內存。而在Java中,內存資源是及其寶貴的,所以,我們就提出了線程池的概念
    2021-10-10
  • 深入理解final變量的初始化

    深入理解final變量的初始化

    本篇文章是對final變量的初始化進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • java實現(xiàn)簡單學生管理系統(tǒng)項目

    java實現(xiàn)簡單學生管理系統(tǒng)項目

    這篇文章主要介紹了java實現(xiàn)簡單學生管理系統(tǒng)項目,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07

最新評論