1. 程式人生 > >談談java創建對象

談談java創建對象

裏的 最大 線程安全 tostring 現實 創建多個對象 語言 安全問題 thread

  作為一門面向對象的語言,我們學習java,對於對象的學習非常重要。大多的教程上都用抽象的概念驅使著我們理解對象,把現實抽象為對象。然而忽略對創建對象的研究。如果說學習抽象思維,運用抽象思維虛擬現實是走向java頂端的關鍵,那創建對象可以說是通向成功的墊腳石吧。今天我們就來談談創建對象。

  說到創建對象,new 方法是java最常用也是最簡單的方式。而恰恰是它的簡單,讓我們用的那麽的隨意。

  舉個例子:

    

public class Demo {
	private String i;
	private String love;
	private String java;
	
	public String getDemo(){
		  return i + love + java;
	}
}

  

  編譯器如果不為我們優化,調用一次getDemo我們將創建2個對象。而我們都清楚,可以使用stringbuffer和stringbuilder代替。

public class Demo {
	private String i;
	private String love;
	private String java;
	
	public String getDemo(){
	    StringBuilder builder = new StringBuilder();
	      builder.append(i);
	      builder.append(love);
	      builder.append(java);
	      return builder.toString();
	}
}

 這樣是解決了調用一次getDemo創建多個對象,但是調用多次getDemo呢??

public class Demo {
	private String i;
	private String love;
	private String java;
	
	private final ThreadLocal<StringBuilder> cache = new ThreadLocal<StringBuilder>(); 
	
	public String getDemo(){
		StringBuilder builder = cache.get();
		if(builder==null){
			builder = new StringBuilder();
			cache.set(builder);
		}else{
			builder.delete(0, builder.length());
		}
		builder.append(i);
		builder.append(love);
		builder.append(java);
		return builder.toString();
	}
}

  

  

public class Demo {
	private String i;
	private String love;
	private String java;
	
	private final ThreadLocal<StringBuilder> cache = new ThreadLocal<StringBuilder>(); 
	
	public String getDemo(){
		StringBuilder builder = cache.get();
		if(builder==null){
			synchronized (this) {
				builder = new StringBuilder();
				cache.set(builder);
			}	
		}else{
			builder.delete(0, builder.length());
		}
		builder.append(i);
		builder.append(love);
		builder.append(java);
		return builder.toString();
	}
}

  

  我們使用了成員屬性來解決多次調用getDemo創建多個stringbuilder類型的變量。熟悉多線程的你應該已經考慮安全的問題了。是的,使用成員屬性容易引起線程安全問題。上面代碼裏的判斷非空和set是非安全的。我們做修改後如下:

  我們編寫的程序,方法中每個new操作,運行在多線程情況下,最終會產生n個對象。我們知道new 創建的對象存在於堆中,它不會隨著線程的執行結束而釋放。而對於這些對象的回收,我們需要jvm的垃圾回收來完成,而垃圾回收什麽時候開始,回收效果如果,我們往往不會去關註。

  可以確定的是,我們都希望著jvm立刻回收不需要使用的對象,以便我們可以最大限度的使用內存。但是我們為什麽不從源頭,從創建的時刻,盡量少的使用它呢。

  以上是我個人的理解,如有錯誤,敬請糾正。   

  

談談java創建對象