Java靜態(tài)方法是使用公共內(nèi)存空間的,就是說所有對象都可以引用,而且在沒有創(chuàng)建對象時也可以利用類使用該方法。
例如,我創(chuàng)建一個類,里面有一個靜態(tài)方法:
class Test{
public static int z(int xx,int yy){
return xx+yy;
}
public int zz(int xx,int yy){
return xx+yy;
}
}
然后在含有main方法的類中使用這個類時,對與以上非靜態(tài)和靜態(tài)方法的引用方式是不同的,如下:
import Test;
public class mainClass{
int sum;
public static void main(String args[]){
sum=Test.z(1,2); //直接用 類.方法或者屬性就可以使用該方法或?qū)傩浴?
System.out.println(sum);
Test t=new Test();
sum=t.zz(1,2); //因為zz不是靜態(tài)方法,所以只能只能用Test類創(chuàng)建一個t對象,然后調(diào)用該對象的方法。
System.out.println(sum);
}
}
靜態(tài)方法可以調(diào)用靜態(tài)方法,但不能調(diào)用成員方法。
wait():使一個線程處于等待狀態(tài),并且釋放所持有的對象的lock。
sleep():使一個正在運知行的線程處于睡眠狀態(tài),是一個靜態(tài)方法,調(diào)用此道方法要捕捉InterruptedException異常。
notify():喚醒一個處于等待狀態(tài)的線程,注意的是在調(diào)用此方法的時候,并不專能確切的喚醒某一個等待狀態(tài)的線程,而是由JVM確定喚醒哪個線程,而且不是按優(yōu)先級。
Allnotity():喚醒所有處入等待狀態(tài)的線程,注意并不是給所有喚醒線程一個對象的鎖,而是讓屬它們競爭。
靜態(tài)方法、靜態(tài)變量,方便了開發(fā)中的操作,不需要實例則可以調(diào)用,但是往往卻破壞了一些屬性的封裝,使得在安全性方面大大降低,在內(nèi)存使用上和實例變量有著不同的地方,靜態(tài)變量或方法他是在程序一運行類一加載的時候就會為他分配了一塊內(nèi)存地址,相當(dāng)于初始化了這些靜態(tài)變量,而實例變量或?qū)傩允侵挥挟?dāng)對象被實例的時候才會為這些屬性分配地址,也就是說在程序運行的時候,如果是小程序,那么在使用過程中占用的內(nèi)存會隨著你實例的創(chuàng)建而逐步增加,對象需要被共享的時候,這時候可以考慮單例模式(只有一個實例),保證不會浪費內(nèi)存地址,當(dāng)然這要符合實際,但是如果是一個比較大的項目,重用性強,變量需要被共享的時候,就可以考慮用static來解決。
可以多多交流哦 交流群:45271133。
總的結(jié)論:java是線程安全的,即對任何方法(包括靜態(tài)方法)都可以不考慮線程沖突,但有一個前提,就是不能存在全局變量。如果存在全局變量,則需要使用同步機制。
如下通過一組對比例子從頭講解:
在多線程中使用靜態(tài)方法會發(fā)生什么事?也就是說多線程訪問同一個類的static靜態(tài)方法會發(fā)生什么事?是否會發(fā)生線程安全問題?
public class Test {
public static void operation(){
// 。 do something
}
}
事實證明只要在靜態(tài)函數(shù)中沒有處理多線程共享數(shù)據(jù),就不存在著多線程訪問同一個靜態(tài)方法會出現(xiàn)資源沖突的問題。下面看一個例子:
public class StaticThread implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
StaticAction.print();
}
public static void main(String[] args) {
for (int i = 0; i
在java5以前實現(xiàn)多線程有兩種方法(繼承Thread類和實現(xiàn)Runnable接口)
它們分別為:
使用new Thread()和new Thread(Runnable)形式
第一種直接調(diào)用thread的run方法,所以,往往使用Thread子類,即new SubThread()。
第二種調(diào)用
Runnable的run方法。
第一種:
new Thread(){}.start();這表示調(diào)用Thread子類對象的run方法,new Thread(){}表示一個Thread的匿名子類的實例對象,子類加上run方法后的代碼如下:
new Thread(){
public void run(){
}
}.start();
第二種:
new Thread(
new Runnable(){}
).start();
這表示調(diào)用Thread對象接受的Runnable對象的run方法,new Runnable(){}表示一個Runnable的匿名子類的實例對象,
runnable的子類加上run方法后的代碼如下:
new Thread(new Runnable(){
public void run(){
}
}
).start();
類的成員分為兩類,靜態(tài)成員(static member)和實例成員(instance member)。靜態(tài)成員屬于類,實例成員則屬于對象,即類的實例。
簡單討論一下在一個類中使用靜態(tài)字段(static field)和靜態(tài)方法(static method)是否會有線程安全問題。
我們在知道, 靜態(tài)字段(static field)和靜態(tài)方法(static method)的調(diào)用是通過類來調(diào)用。靜態(tài)方法不對特定的實例操作,只能訪問靜態(tài)成員。實例方法可對特定的實例操作,既能訪問靜態(tài)成員,也能訪問實例成員。
那么,在多線程中使用靜態(tài)方法是否有線程安全問題?這要看靜態(tài)方法是是引起線程安全問題要看在靜態(tài)方法中是否使用了靜態(tài)成員。
因為,在多線程中使用同一個靜態(tài)方法時,每個線程使用各自的實例字段(instance field)的副本,而共享一個靜態(tài)字段(static field)。所以說,如果該靜態(tài)方法不去操作一個靜態(tài)成員,只在方法內(nèi)部使用實例字段(instance field),不會引起安全性問題。但是,如果該靜態(tài)方法操作了一個靜態(tài)字段,則需要靜態(tài)方法中采用互斥訪問的方式進(jìn)行安全處理。
舉個簡單的例子,我們使用的Console.WriteLine();中WriteLine()是Console.WriteLine類的靜態(tài)方法。
對于ASP.NET, 多個客戶端訪問服務(wù)器端, 這是一個多線程的例子.只要理解了原因,我們可以在三層架構(gòu)中的數(shù)據(jù)訪問層中放心使用靜態(tài)方法(static method)來訪問數(shù)據(jù)庫.
先看一個類:
public class Test
{
public static String hello(String str)
{
String tmp = "";
tmp = tmp + str;
return tmp;
}
}
hello方法會不會有多線程安全問題呢?沒有!
靜態(tài)方法如果沒有使用靜態(tài)變量,則沒有線程安全問題。
為什么呢?因為靜態(tài)方法內(nèi)聲明的變量,每個線程調(diào)用時,都會新創(chuàng)建一份,而不會共用一個存儲單元。比如這里的tmp,每個線程都會創(chuàng)建自己的一份,因此不會有線程安全問題。
注意:靜態(tài)變量,由于是在類加載時占用一個存儲區(qū),每個線程都是共用這個存儲區(qū)的,所以如果在靜態(tài)方法里使用了靜態(tài)變量,這就會有線程安全問題!
這要看靜態(tài)方法中有沒有操作靜態(tài)成員變量了,看代碼吧
public class StaticMethod implements Runnable {
static int num=0;
public static void addOne() throws InterruptedException {
for (int i = 0; i <= 10; i++) {
num += i;
}
System.out.println(Thread.currentThread().getName() + "-" + num);
num=0;
}
}如上面代碼所示,當(dāng)單線程運行情況下是輸出正常的,num最后應(yīng)該輸出55,但是在多線程情況下,則會出現(xiàn)每個線程輸出的num不一樣的情況,這是因為num是靜態(tài)成員變量,為多個線程所共享的,有可能會出現(xiàn)一個線程的num值還沒有重新賦值為0,另外一個線程已經(jīng)讀取到num的累加后的值,所以說,多線程情況下,靜態(tài)方法中如果操作靜態(tài)成員變量,那這個靜態(tài)方法就不是線程安全的
聲明:本網(wǎng)站尊重并保護(hù)知識產(chǎn)權(quán),根據(jù)《信息網(wǎng)絡(luò)傳播權(quán)保護(hù)條例》,如果我們轉(zhuǎn)載的作品侵犯了您的權(quán)利,請在一個月內(nèi)通知我們,我們會及時刪除。
蜀ICP備2020033479號-4 Copyright ? 2016 學(xué)習(xí)鳥. 頁面生成時間:2.468秒