1. 程式人生 > >【多執行緒】實現執行緒同步的幾種方法(一)

【多執行緒】實現執行緒同步的幾種方法(一)

前言

最近小扁我被問到 實現執行緒同步有哪幾種方法,而我只知道使用同步關鍵字synchronized來實現而已(⊙o⊙),,所以有必要來學習一下實現執行緒同步的幾種方法;各位看官,若有非議(不接受反駁),請不吝賜教!

實現執行緒同步的幾種方法

從我自己比較理解的方法講起,後面的幾種方法我現在也不是很理解,各位看官可以閱讀這篇文章的參考文章


1. 使用同步關鍵字synchronized
synchronized主要有兩種使用方式
1.1 同步方法
使用synchronized修飾方法
使用模板:

//同步方法
public synchronized void methodName(...
){...} //同步靜態方法 public synchronized static void methodName(...){...}

注意:當使用synchronized修飾靜態方法時,執行緒此時獲得的鎖物件是類的Class物件(堆記憶體中只有唯一一個Class物件,因為Class物件是在類載入時產生的,而類載入只執行一次),因此會鎖住整個類,其他執行緒無法訪問該類的同步靜態方法,但是可以訪問非同步的方法

1.2 同步程式碼塊
使用synchronized修飾程式碼塊
使用模板:

synchronized(object){...}

注意

1. 同步通常會導致執行緒堵塞,使得程式執行效率低,
   因此應該儘量縮小同步範圍。

2. 
基於第1點,通常沒必要同步整個方法, 只需要同步關鍵程式碼塊(操作了共享變數的區域)

2. 使用關鍵字volatile修飾共享變數實現偽同步

1. volatile為所修飾的共享變數提供了一種免鎖機制,
   並沒有為共享變數上鎖。

2. 使用volatile;
   相當於告訴JVM某個共享變數隨時可能被其他執行緒修改,
   需要執行緒到記憶體中去讀取這個共享變數的值,
   而不是從快取中讀取

3. volatile僅保證可見性;
   volatile所修飾的共享變數的值被修改時,會被立即更新到記憶體中


4. volatile不保證原子性

5. volatile
不能修飾final變數 基於第2點,volatile修飾的變數隨時可能會被修改, 而final修飾的變數是不會被修改, 因此volatile不能修飾final變數

為什麼說實現的是偽同步
主要基於以上的第3,4點原因,volatile保證了可見性,相對於沒有用volatile修飾的共享變數,大大提高了執行緒讀取到最新資料的可能性,但是volatile不保證原子性,說明執行緒讀到的最新資料可能並不是真正意義上的最新

後記

暫時先寫這麼多,雖然寫的不多,但是一大早地,起來學習理解,再將理解整理成文,真素腦闊疼啊,後續再根據我個人的學習進度及理解程度,繼續更新

相關推薦

執行實現執行同步方法

前言 最近小扁我被問到 實現執行緒同步有哪幾種方法,而我只知道使用同步關鍵字synchronized來實現而已(⊙o⊙),,所以有必要來學習一下實現執行緒同步的幾種方法;各位看官,若有非議(不接受反駁),請不吝賜教! 實現執行緒同步的幾種方法 從我自己

Python3.5+PyQt5執行+itchat實現微信防撤回桌面版

前幾日在某乎看到有大神用itchat實現了微信防撤回功能,,覺得很有趣,看到下面評論很多人求桌面版,於是乎,手癢便利用清明節幾天時間做了一個簡陋的桌面程式。廢話不多說,先上圖位敬。 執行環境 win10專業版64位系統1703創造者更新 開發環

網路程式設計基礎林老師版:簡單的 套接字通訊

一、服務端程式碼  import socket #1、買手機 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # print(phone) #2、繫結手機卡 phone.bind(('127.0.0.1',8081)) #0-

cocos2dx網路遊戲搭建CS架構的基本通訊框架server

#include <iostream> using namespace std; #include "comm.h" void proc_data(socket_type sock) { //輸出客戶端的地址的字串 cout<<"client connected :"<&

用OpenCV實現目標追蹤的八方法

原文地址:http://m.elecfans.com/article/722414.html 編者按:目標跟蹤作為機器學習的一個重要分支,加之其在日常生活、軍事行動中的廣泛應用,很多國內外學者都對此頗有研究。本文將討論OpenCV上八種不同的目標追蹤演算法。

Android 實現懸浮的方式AppBarLayout+PtrFrameLayout

先上個圖: 我所知道的有兩種實現方式: AppBarLayout巢狀控制滾動區實現(目前使用的) 給RecyclerView增加HeaderView顯示隱藏切換實現 先把引用的包放出來: compile 'com.android.su

Android 實現滑動的方法scrollTo 與 scrollBy

scrollTo(x,y): 表示移動到一個座標點(x,y) scrollBy(dx,dy) : 表示移動的增量為dx,dy 如果在ViewGroup中使用scrollTo和scrollBy,那麼移

java建立執行的四方法

java中建立執行緒的四種方法以及區別 Java使用Thread類代表執行緒,所有的執行緒物件都必須是Thread類或其子類的例項。Java可以用四種方式來建立執行緒,如下所示: 1)繼承Thread類建立執行緒 2)實現Runnable介面建立執行緒 3)使用Callable和Future建立執行緒

java間執行通訊的方式II

1.如何讓兩個執行緒嫩能夠交叉執行 要讓執行緒能夠交叉執行,需要用到鎖。看如下程式碼: package Test;/** /** * @author Administrator wangtao * @createdate 2017-10-10 */ public class

執行使用使用者介面的四方法BackgroundThreadUpdateUI

namespace BackgroundThreadUpdateUI { // For Method Two public delegate void SetTextCallback(string text); public partial cl

Java定時任務的方法Thread 和 Timer,執行

/**   * 普通thread   * 這是最常見的,建立一個thread,然後讓它在while迴圈裡一直執行著,   * 通過sleep方法來達到定時任務的效果。這樣可以快速簡單的實現,程式碼如

使用內部類來將執行隱藏在類中的方法

class InnerThread1{ private int countDown=5; private Inner inner; private class Inner extends Thread{ Inner(String na

執行同步的四方式

併發concurent與並行parallel的區別: 互斥物件 首先我們需要建立CreateMutex一把互斥物件,我們可以指明當前執行緒是否擁有它,互斥物件完全就像一把鑰匙一樣,我們用WaitForSignalObject來等待這把鑰匙,但是這把鑰匙被等到

執行掛起和恢復的方法

執行緒掛起和恢復方法(1):sleep()方法 此種方法比較簡單,哪個執行緒需要掛起就在哪個執行緒中直接呼叫:Thread.sleep(掛起的毫秒數); 執行緒掛起和恢復方式(2):join()方法 在實現多執行緒的兩種方法這篇博文中值說明了Threa

JS深拷貝與淺拷貝的區別,實現深拷貝的方法

如何區分深拷貝與淺拷貝,簡單點來說,就是假設B複製了A,當修改A時,看B是否會發生變化,如果B也跟著變了,說明這是淺拷貝,拿人手短,如果B沒變,那就是深拷貝,自食其力。 此篇文章中也會簡單闡述到棧堆,基本資料型別與引用資料型別,因為這些概念能更好的讓你理解深拷貝與淺拷貝。 我們來舉個淺拷貝例

Android實現XML解析的技術

轉載地址:http://www.cnblogs.com/hanyonglu/archive/2012/02/28/2370675.html  謝謝。 本文介紹在Android平臺中實現對XML的三種解析方式。   XML在各種開發中

Nginx實現負載均衡的方式

要理解負載均衡,必須先搞清楚正向代理和反向代理。 正向代理與反向代理【總結】 注: 正向代理,代理的是使用者。 反向代理,代理的是伺服器 什麼是負載均衡 當一臺伺服器的單位時間內的訪問量越大時,伺服器壓力就越大,大到超過自身承受能力時,伺服器就會崩潰。為了避免伺服器崩潰

Android UI設計與開發第06期:底部選單欄使用TabActivity實現底部選單欄

轉載請註明出處:http://blog.csdn.net/yangyu20121224/article/details/8989063               從這一篇文章開始,我們將進入到一個應用程式主介面UI的開發和設計中了,底部選單欄在Android的應用開發當

Android進階如何寫一個很屌的動畫1---先實現一個簡易的自定義動畫框架

class MyView extends View { public void onDraw(Canvas canvas) { super.onDraw(canvas); invalidate(); } } 這樣一來,View每次繪製都是觸發下一次繪製,不過

SpringBoot 基礎系列實現一個自定義配置載入器應用篇

![](https://spring.hhui.top/spring-blog/imgs/200507/logo.jpg) > [【SpringBoot 基礎系列】實現一個自定義配置載入器(應用篇)](https://mp.weixin.qq.com/s?__biz=MzU3MTAzNTMzMQ==&