1. 程式人生 > >多執行緒中使用靜態方法存線上程安全的問題

多執行緒中使用靜態方法存線上程安全的問題

   類的成員分兩類,靜態成員(static member)和例項成員(instance menber),靜態成員屬於類,例項成員則屬於物件,即類的例項。
   我們知道,靜態欄位和靜態方法的呼叫都是通過類來呼叫的,靜態方法不會對特定的例項操作,只能呼叫呼叫類中的其他屬性和靜態方法,不能呼叫類中的非靜態屬性和非靜態方法。例項方法可以對特定的例項操作,既能訪問靜態屬性和靜態方法,也能訪問例項屬性和例項方法。

   在多執行緒中使用靜態方法是否有安全問題?這樣看在靜態方法中時候使用了靜態成員。在多執行緒中使用一個靜態方法的時候,每個執行緒共享一個靜態欄位,如果該靜態方法不去操作一個靜態變數,只在方法內部使用區域性變數,則不會造成安全性問題。但是,如果該靜態方法操作了一個靜態欄位,則需要在靜態方法中採用互斥訪問的方式來對其進行安全處理。

   先來看沒有執行緒安全問題的例項:

 public class Test
 {
    public static String hello(String str)
    {
        String tmp = "";
        tmp = tmp + str;
        return tmp;
    }
 }
    上述示例中是執行緒安全的,這是因為在靜態方法中聲明瞭區域性變數,每個執行緒在呼叫的時候,都會建立一份新的區域性變數,比如這裡的tmp,而不會共享一個儲存單元。

    以下是執行緒不安全的:

   public class Test
 {
   Private static Test test
    public static Test hello()
{
If(tets==null)
  Test=new Test();        
return test;
    }
 }
     這是因為在靜態方法中又返回了靜態變數,對於靜態變數來說,類在載入的時候會佔用同一個儲存區,而每個執行緒都是公用這個儲存區的,因此存線上程安全的問題。
    因此在設計工具類的時候,對於沒有使用到靜態變數的靜態工具類方法,是不需要加鎖的(synchronized)。
  在使用單例模式做工具類的時候,這個時候靜態方法需要被加鎖,這是因為所有的執行緒雖然有自己的方法棧,但是在方法棧中操作的是同一個物件的實體,所以需要進行加鎖同步,來實現每個執行緒都需要等待鎖的釋放才能使用該物件的引用。
    但是在多例模式做工具類的時候,是不需要加鎖的,因為每個執行緒中有自己的方法棧,但是在方法棧中建立了獨立的物件引用,可以看成是執行緒都是在自己的方法棧中操作區域性的物件引用,因此這個時候不需要同步。

相關推薦

執行使用靜態方法線上安全的問題

   類的成員分兩類,靜態成員(static member)和例項成員(instance menber),靜態成員屬於類,例項成員則屬於物件,即類的例項。    我們知道,靜態欄位和靜態方法的呼叫都是通過類來呼叫的,靜態方法不會對特定的例項操作,只能呼叫呼叫類中的其他屬性和

C# 執行呼叫靜態方法或者靜態例項的同一個方法-方法內部的變數是執行安全

 C#  多執行緒呼叫靜態方法或者靜態例項中的同一個方法-方法內部的變數是執行緒安全的       using System;using System.Threading;using System.Threading.Tasks;using Sys

白話理解java執行join()方法

join字面意思是加入,我理解為插隊. 舉例:媽媽在炒菜,發現沒喲醬油了,讓兒子去打醬油,兒子打完醬油,媽媽炒完菜,全家一起吃 package cn.yh.thread01; /** * *

執行方法、兩種實現方式、匿名內部類建立執行執行安全問題的解決、

多執行緒兩種實現方式: 方式一: 繼承Thread類的方式 方式二: 實現Runnable介面的方式。 方式一: 步驟: // 1. 定義一個類,然後繼承Thread //

JAVA執行join()方法的詳細分析

雖然關於討論執行緒join()方法的部落格已經非常極其特別多了,但是前幾天我有一個困惑卻沒有能夠得到詳細解釋,就是當系統中正在執行多個執行緒時,join()到底是暫停了哪些執行緒,大部分部落格給的例子看起來都像是t.join()方法會使所有執行緒都暫停並等待t的執行完畢。當然

Java執行join方法的理解

[CustomThread1] Thread start.      //執行緒CustomThread1起動 [CustomThread1] Thread loop at 0   //執行緒CustomThread1執行 [CustomThread1] Thread loop at 1   //執行緒Cu

Java執行所有方法的解析

一、run()和start()   這兩個方法應該都比較熟悉,把需要並行處理的程式碼放在run()方法中,start()方法啟動執行緒將自動呼叫 run()方法,這是由Java的記憶體機制規定的。並且run()方法必須是public訪問許可權,返回值型別為void。   二

Java—Java執行join方法的理解

[CustomThread1] Thread start.      //執行緒CustomThread1起動 [CustomThread1] Thread loop at 0   //執行緒CustomThread1執行 [CustomThread1] Thread loop at 1   //執行緒Cu

Java執行join方法的實現

方法join的作用是使所屬的執行緒物件t正常執行run()方法中的任務,而使當前執行緒z進行阻塞,等待t銷燬後再繼續執行z後面的程式碼。 下面貼出join方法的原始碼: public final synchronized void join(long millis)

Java執行注入Spring的Bean-使用靜態方法直接取的容器的spring物件

目前認為比較好的解決方案。 1,工具類 public class SpringApplicationContextHolder implements ApplicationContextAware { private static ApplicationContext context

Java執行static變數的使用 SimpleDateFormat時間格式化線上安全問題

兩篇文章 Java多執行緒中static變數的使用  (轉自:http://blog.csdn.net/yy304935305/article/details/52456771) &&  SimpleDateFormat時間格式化存線上程安全問題

junit測試和main方法執行遇到的問題

利用Junit測試多執行緒時經常遇到任務執行不完就會停止,下面是我的任務執行緒類: package timerTest; import java.io.BufferedReader; import java.io.BufferedWriter; import java.i

Java執行-44-靜態和非靜態方法同步鎖物件是什麼

前面一篇,我們知道了synchronized關鍵字擴起來範圍的程式碼塊就可以實現同步,其實,在Java中,只需要在方法上加上synchronized關鍵字即可,就像加上static一樣。本篇來看看加上synchronized關鍵字修飾的非靜態和靜態方法的同步鎖物件是什麼。 1.非靜態同步鎖物

python執行event的使用-----------------即一個靈活的方法標誌位,類似於java的等待喚醒機制(python與java不同的地方)

event是python中一個特有的標誌位方法,他一共有三種方法 1.event.wait():如果標誌位設定了,它不做任何事,如果沒有設定,則將會鎖住,等待標誌位的設定 2.event.set():設定標誌位 3.event.clear():清除標誌位 這一種機制很

java向執行傳遞引數的三種方法詳細介紹

在傳統的同步開發模式下,當我們呼叫一個函式時,通過這個函式的引數將資料傳入,並通過這個函式的返回值來返回最終的計算結果。但在多執行緒的非同步開發模式下,資料的傳遞和返回和同步開發模式有很大的區別。由於執行緒的執行和結束是不可預料的,因此,在傳遞和返回資料時就無法象函式一樣通過

Pyqt5 執行的編寫方法

對於執行緒的概念就不在此處進行詳細的說明了,下面就說明如何使用: 對於你想要多執行緒的執行的邏輯業務,你都需要例項化一個執行緒物件: class WorkThread(QThread): trigger = pyqtSignal() def __int_

python執行daemon的屬性方法

我們看官方介紹是這樣的: 意思就是說:這個屬性為一個布林值,表示是否為一個守護程序,且這個屬性設定必須線上程的start方法開始之前呼叫。它的值繼承自主執行緒,主執行緒的daemon為False且所有從主執行緒建立的執行緒都是daemon = False 。 下面一句

執行join和detach方法的理解

thread.Join把指定的執行緒加入到當前執行緒,可以將兩個交替執行的執行緒合併為順序執行的執行緒。比如線上程B中呼叫了執行緒A的Join()方法,直到執行緒A執行完畢後,才會繼續執行執行緒B。 join是阻塞當前執行緒,並等待object對應執行緒結束,

執行yield()和join()方法的對比

1.yield():呼叫此方法的執行緒,釋放當前cpu的執行權class SubTread extends Thread{ @Override public void run() { for(int i=1;i<=100;i++){ System.out.

java執行關於join方法的使用

Thread的非靜態方法join()讓一個執行緒B“加入”到另外一個執行緒A的尾部。在A執行完畢之前,B不能工作。例如:         Thread t = new MyThread();         t.start();         t.join(); 另外,j