#
從很小都認識蘋果機了,我不記得我是否在小學的時候學過Basic,只記得大學實驗室里的蘋果機我的確是摸過(得益于我是教師子弟,有“特殊待遇”),也看到計算機系的學生們編寫的游戲。初中,有了自己的游戲機。玩過魂斗羅,坦克。當時覺得很不過癮,心想以后能自己編寫游戲就好了,于是立志以后做個程序員。
高考不順利,只考上了普通學校電力專業。這還是幸虧當時學校的羅老師(那四年,她一直都在幫助我)看到我以前的成績還不錯,決定要下我,否則,我就往下落的更厲害了。電力專業幾乎沒有計算機課程。等到學校關于自動化的時候,開始接觸了匯編,和自學了C.當時很羨慕學計算機的那個女老鄉,姓楊,呵呵,因為羨慕,還被別人誤認為我喜歡她,其實完全不是,她根本對計算機沒有興趣,畢業后也去了當公務員,可惜啊,早知道如此,她何必要高出幾分,占據我喜歡的專業呢,我甚至為此感到暗自不爽。 不過大學還是學到了一些計算機皮毛知識,C程序寫的很好,記得寫了一個模仿TT的打字程序。匯編也不錯,寫個文件病毒,源代碼10K,編譯鏈接后3K多,很大,AV95能識別出來,我想大概是我寫的太爛,別的殺毒程序,象KV300,都不認為這是個病毒。不管怎么樣,我沒有拿這個干啥壞事情。這始終是不光彩的事情。
該畢業了,家鄉的供電局沒能進去。我怨我老媽沒有幫我跑關系,其實我跟我老媽都不愿意我去,我老媽是不想讓我回銅仁,我自己也不想做電力職工(雖然在我們那是一等的暴有錢的工作),我還是喜歡去做個程序員,為此也退掉了別的電力相關的工作。但是,我始終不到該如何入門。畢業了,門衛老頭開始趕我們出去,我工作無著落,同學們都已經回到家鄉開始上班了,我還在跟老頭打游擊。他進我退,他退我上床休息,有次晚上洗澡,被他發現,嚇得我光著屁股從三樓跑到5樓,再跑回三樓。呵呵,那時候整個宿舍樓都空了,所以也不算丟臉了。
好運終于堅持到了,網上碰到一網友,后來我叫他秦哥,他說他需要一個人幫他做個網站。我便毛遂自薦了一下,其實,那時候我不懂做網站,不懂ASP,不過我相信我的能力,果然,一段適應時間后,我成了他得力的幫手,我也開始正式進入程序員這個行業了。相比現在的很多學生,我覺得他們比我幸運多了,在大學的時候都已經學習到很多知識,甚至是已經有一定的實踐了。剛畢業就能踏入這行,還能有地方住,要知道我不光要跟老頭打游擊,有時候還睡在電腦城廣場的板凳上,早上起來看的第一眼便是保安和他身邊對我俯視眈眈的狼狗。
搞懂了ASP和網站后,開始考慮學更多的東西,這時候我已經放棄了我編寫游戲程序的夢想了,因為我跟本不知道如何去追逐這個夢想。我也放棄了我比較擅長的單片機開發(現在應該叫嵌入式)。我轉向了Java.俗話說,女怕嫁錯狼,男怕入錯行。8年前的這個時候,我算是馬馬虎虎開始我的JavaEE道路吧,這兒有點體會就是一定要堅持自己的理想,而這個理想,應該能養活你的,能讓你有興趣做的事情。
初學Java,有些迷惑,當時微軟有個VJ++,我先買了一本介紹這樣的書看,結構后來發現它主要是桌面程序的,而且,跟我知道的JSP不太一樣。當時也沒有想到可以找人問或者論壇上發給帖子問。幸好后來明智的轉到了JSP,挺簡單,跟ASP差不多,tb概念都能通用(畢竟處理的問題都一樣嘛),比起現在的孩子來說,我當時學的東西太少了,不用學習hibernate,spring,j2ee,也不用學習ant,Junit什么的,呵呵,關鍵還是當時書太少,見識少,也沒有這么多新玩意。好處就是我能深入JSP技術,為以后理解這些Web框架打下了很好的基礎。不象現在的孩子,還搞不懂JSP,就去弄MVC,搞的本末倒置了。
J2EE技術得到提高得益于后來到了北京,去了ZZ公司,現在看來,好不夸張的說,從這個公司出來的程序員,都有一定創新能力和解決問題能力。一到這公司,就做了一個算是大的項目,幾十個人,還包括國防科技大學的數十個博士,當時用到了很多J2EE技術,象EJB,JMS都用到了,當時不懂這些,費了很多力氣去學,還好項目本身就是個很好的學習材料。通過專研項目代碼學到了不少東西,遠比看書強多了。現在的很多培訓方式都是通過做獨立完成項目來學習技術,這是很有道理的。當時那個項目做了一年,期間我對自己要求蠻高的,總會多學點東西,比如學了EJB 無狀態會話Bean,雖然項目沒有用到有狀態Bean,但還是花時間去搞明白。這個項目期間,頭一次知道了還有英文資料這么一說,象什么Weblogic使用說明,Java文檔都,我都會強迫自己去看,有時候打印下來,躺在小床,打開臺燈看,那感覺真是美阿。
對于J2ME編程開發平臺,在其他平臺風生水起的時候,J2ME編程開發平臺似乎很沉寂。本文將簡單介紹一下幾個J2ME編程開發平臺的重要概念。
內存
我們一直在強調,移動信息設備的內存非常小,使用起來應該加倍的珍惜,但是我們卻很少知道這些內存是如何分類的,下面將做詳細的介紹。事實上MIDP設備的內存分為三種,
1.ProgrammeMemory、Heap、persistentStorage
ProgrammeMemory是移動信息設備分配給MIDletsuite的空間,因為MIDletsuite是以jar文件進行發布的,所以這個文件的大小可以認為是ProgrammeMemory的大小。一些廠商對ProgrammeMemory的最大值是有限制的,例如我的Nokia6108的最大值是64k,超過的話將不能進行安裝。減小MIDletsuite的大小非常重要,一個便捷的方法就是使用混淆器對應用程序進行混淆,這樣可以減小jar文件的大小。在以后的文章中我會談到如何使用Proguard.
Heap是應用程序在運行過程中存放所創建的對象的存儲空間,tb本地變量和成員變量也是放在Heap上的,MIDP設備中提供的Heap空間大概在幾十k到幾百K.
PersistentStorage的空間是用來實現MIDP應用程序的本地數據持久性存儲的,在RecordManagementSystem從入門到精通中我做了詳細的介紹這里就不再多說了。
2.ConnectedLimitedDeviceConfiguration
CLDC包括一個Java虛擬機和一系列的基礎類,J2ME的專家組經過對移動信息設備進行硬件抽象后得到他們的特點,然后設計并實現了在移動信息設備上運行的java虛擬機,通常我們把它叫做KVM.在CLDC1.0還同時提供了由java.io、java.lang、javax.microediton.io、java.util組成的基礎類。在CLDC1.1里面添加了java.lang.ref.
3.MobileInfomationDeviceProfile
MIDP是運行在CLDC基礎之上的,在MIDP中定義了應用程序的生命周期、用戶圖形界面、數據管理系統等子集,從而構建起了J2ME平臺。通常,J2ME平臺由一個CLDC和一個或者多個Profile構成。
Jquery是繼prototype之后又一個優秀的Javascrīpt框架。它是輕量級的js庫,除了兼容CSS3外,還兼容各種瀏覽器+)。jQuery使用戶能更方便地處理HTML documents、events、實現動畫效果,并且方便地為網站提供AJAX交互。
HTML5 中新定義的 HTML 元素,可以用來在 HTML 頁面中通過 JavaScriptb 繪制圖形、制作動畫。現在要推薦的 jCanvas 就是一個 jQuery 的繪圖插件,它封裝了一些繪制圖形的方法,只需編寫幾行代碼即可生成圖形。
以下是JCanvas 繪制窗口并對其監聽的程序代碼分享
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class JCanvas extends JComponent
{
public JCanvas()
{
setDoubleBuffered(true);
}
public void paintComponent(Graphics g)
{
Dimension size = getSize();
g.setColor(getBackground());
g.fillRect(0,0,size.width,size.height);
}
}
class TestJCanvas
{
public static void main(String s[] )
{
MyWindowListener l = new MyWindowListener();
JCanvas c = new JCanvas();
c.setBackground(Color.yellow);
JFrame f = new JFrame("Test JCanvas...");
f.addWindowListener(l);
f.getContentPane().add(c,BorderLayout.CENTER);
f.pack();
f.setSize(500,400);
f.show();
}
}
class MyWindowListener extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
雖然jQuery上手簡單,相比于其他庫學習起來較為簡單,但是要全面掌握,卻不輕松。因為它涉及到網頁開發的方方面面,提供的方法和內部變化有上千種之多。初學者常常感到,入門很方便,提高很困難。本文的目標是將jQuery選擇器做一個系統的梳理,試圖理清jQuery的設計思想,找出學習的脈絡,使讀者從入門到精通。
jQuery是什么
簡單的說,jQuery是一個JavaScript框架,它的宗旨是:寫更少的代碼,做更多的事情。對于Web開發人員而言,jQuery是一個功能強大的JavaScript庫,能更加快速開發相關應用,例如AJAX交互,JavaScript動畫效果等。對于Web設計師而言,jQuery封裝了Javascript源碼細節,實現了與HTML標簽的有效分離,便于設計師更加專注于Web頁面設計效果。基于此,網頁的用戶體驗大大增強,包括網頁的交互性,視覺效果等等。
jQuery的核心設計思想是:選擇某個網頁元素,然后對其進行某種操作。那么如何選擇、定位某個網頁元素呢?對于JavaScript開發人員而言,通常的一種手段是document.getElementById()。而在jQuery語法中,使用的是美元符號“$”,等價的選擇表達式寫法為:
var someElement = $("#myId");
jQuery之所以稱之為“jQuery”,主要就是因為它強大的選擇器,也就是Javascript Query的意思。下面,我們具體介紹jQuery選擇器相關的設計思想:
一、jQuery基本選擇器
前面提到,選擇器是jQuery的特色。jQuery的基本選擇器主要分為tb以下五種類型:
1. $(“#myId”) // 選擇ID為myId的網頁元素
2. $(“標簽名”) // 例如$(“div”)獲取的就是HTML文檔中的所有的div元素的jQuery對象集合
3. $(“.myClass”) // 獲取的是HTML文檔中所有的class為“myClass”的元素集合
4. $(“*”) // 這個獲取的是HTML文檔中的所有的元素
5. $(“selector1,selector2,selector3…selectorN “) // 這種選擇器叫做組選擇器。例如:$(“span,#two”)
// 選取所有的span標簽元素和id=two的元素。
二、jQuery層次選擇器
無論何時,通過jQuery選擇器獲取的jQuery對象任何時候都是一組元素。jQuery的層次選擇器主要分為以下兩種類型:
1. $(“ancestor descendant”):選取parent元素后所有的child元素。ancestor的中文意思是“祖先”,descendant的中文意思是“后代”。例如:
$(“body div”) 選取body元素下所有的div元素。
$(“div#test div”) 選取id為“test”的div所包含的所有的div子元素
2. $(“parent > child”):選取parent元素后所有的第一個child元素。例如:
$(“body > div”) 選取body元素下所有的第一級div元素。
$(“div#test > div”) 選取id為“test”的div所包含的所有的第一級div子元素
三、jQuery過濾選擇器
jQuery最基本過濾選擇器包括:
1. :first // 選取第一個元素。$(“div:first”)選取所有div元素中的第一個div元素
2. :last // 選取最后一個元素。$(“div:last”)選取所有div元素中的最后一個div元素
3. :even // 選取索引是偶數的所有元素。$(“input:even”)選取索引是偶數的input元素。
4. :odd // 選取索引是奇數的所有元素。$(“input:odd”)選取索引是奇數的input元素。
5. :eq(index) // 選取索引等于index的元素。$(“input:eq(1)”)選取索引等于1的input元素。
6. :gt(index) // 選取索引大于index的元素。$(“input:gt(1)”)選取索引大于1的input元素。
7. :lt(index) // 選取索引小于index的元素。$(“input:lt(3)”)選取索引小于3的input元素。
jQuery內容過濾選擇器,可以輕松地對DOM文檔中的文本內容進行篩選,從而準確地選取我們所需要的元素。
1. :contains(text) // 選取含有文本內容為“text”元素。$(“div:contains(‘你’)”)選取含有文本“你”的div元素。
2. :empty // 選取不包含子元素和文本的空元素。$(“div:empty”)選取不包含子元素(包括文本元素)的div空元素。
3. :parent // 選取含有子元素或者文本的元素。$(“div:parent”)選取擁有子元素(包括文本元素)的div元素。
可以看見,jQuery內容過濾選擇器的過濾規則主要體現在它所包含的子元素或文本內容上。
jQuery可見性過濾選擇器的用法如下:
1. :hidden // 選取所有不可見的元素。$(“:hidden”)選取網頁中所有不可見的元素。
2. :visible // 選取所有可見元素。$(“div:visible”)選取所有可見的div元素。
jQuery屬性過濾選擇器的過濾規則是通過元素的屬性來獲取相應的元素。
1. [attribute] // 選擇擁有此屬性的元素。$(“div[id]“)選取擁有屬性id的元素。
2. [attribute=value] // 選取屬性值為value的元素。$(“div[name=test]“)選取屬性name的值為“test”的div元素。
3. [attribute!value] // 選取屬性值不等于value的元素。
4.[attribute^=value] // 選取屬性的值以value開始的元素。
5. [attribute$=value] // 選取屬性的值以value為結束的元素。
6. [attribute*=value] // 選取屬性的值含有value的元素。
7. [selector1] [selector2] [selectorN] //復合屬性選擇器。$(“div[id][name*=test]“)選取擁有屬性id,且屬性name的值含有“test”的div元素
jQuery子元素過濾選擇器的過濾規則相對于其它的選擇器稍微有些復雜。
1. :nth-child(index/even/odd/equation) // 選取每個父元素下的第index個子元素或者奇偶元素。
2. :first-child // 選取每個父元素的第一個子元素
3. :last-child // 選取每個父元素的最后一個子元素
jQuery表單對象屬性過濾選擇器主要是對所選擇的表單元素進行過濾,例如選擇不可用的表單元素、被選中的下拉框、多選框等等。
1. :enabled // 選取所有可用的表單元素。$(“#form1 :enabled”)選取id為“form1”的表單內的所有可用元素。
2. :disabled // 選取所有不可用的表單元素。
3. :checked // 選取所有被選中的元素。$(“input:checked”)選取所有被選中的元素。
4. :selected // 選取所有被選中的選項元素。$(“select :selected”)選取所有被選中的選項元素(option)。
jQuery中引入了表單選擇器,讓我們能極其方便地獲取到一個表單中的某個或某類型的元素。
在前一節實現異步調用的基礎上 , 現在我們來看一下一個完善的 Java 異步消息處理機制 .
[ 寫在本節之前 ]
在所有這些地方 , 我始終沒有提到設計模式這個詞 , 而事實上 , 多線程編程幾乎每一步都在應該設計模式 . 你只要能恰如其份地應用它 , 為什么要在意你用了某某名稱的模式呢 ?
一個說書人它可以把武功招數說得天花亂墜 , 引得一班聽書客掌聲如雷 , 但他只是說書的 . 真正的武林高手也許并不知道自己的招式在說書人口中叫什么 , 這不重要 , 重要的是他能在最恰當的時機把他不知名的招式發揮到極致 !
你了解再多的設計模式 , 或你寫出了此類的著作 , 并不重要 , 重要的是你能應用它設計出性能卓越的系統 .
本節的這個例子 , 如果你真正的理解了 , 不要懷疑自己 , 你已經是 Java 高手的行列了 . 如果你拋開本節的內容 , 五天后能自己獨立地把它再實現一次 , 那你完全可以不用再看我寫的文章系列了 , 至少是目前 , 我再也沒有更高級的內容要介紹了 .
上節的 Java 異步調用為了簡化調用關系 , 很多角色被合并到一個類中實現 , 為了幫助大家改快地抓住核心的流程 . 那么一個真正的異步消息處理器 , 當然不是這樣的簡單 .
一. 它要能適應不同類型的請求 :
本節用 makeString 來說明要求有返回值的請求 . 用 displayString 來說明不需要返回值的請求 .
二. 要能同時并發處理多個請求 , 并能按一定機制調度 :
本節將用一個隊列來存放請求 , 所以只能按 FIFO 機制調度 , 你可以改用 LinkedList, 就可以簡單實現一個優先級 ( 優先級高的 addFirst, 低的 addLast).
三. 有能力將調用的邊界從線程擴展到機器間 (RMI)
四. 分離過度耦合 , 如分離調用句柄 ( 取貨憑證 ) 和真實數據的實現 . 分離調用和執行的過程 , 可以盡快地將調返回 .
現在看具體的實現 :
public interface Axman {
Result resultTest(int count,char c);
void noResultTest(String str);
}
這個接口有兩個方法要實現 , 就是有返回值的調用 resultTest 和不需要返回值的調用
noResultTest, 我們把這個接口用一個代理類來實現 , 目的是將方法調用轉化為對象 , 這樣就可以將多個請求 ( 多個方法調 ) 放到一個容器中緩存起來 , 然后統一處理 , 因為 Java 不支持方法指針 , 所以把方法調用轉換為對象 , 然后在這個對象上統一執行它們的方法 , 不僅可以做到異步處理 , 而且可以將代表方法調用的請求對象序列化后通過網絡傳遞到另一個機器上執行 (RMI). 這也是 Java 回調機制最有力的實現 .
一個簡單的例子 .
如果 1: 做 A
如果 2: 做 B
如果 3: 做 C
如果有 1000 個情況 , 你不至于用 1000 個 case 吧 ? 以后再增加呢 ?
所以如果 C/C++ 程序員 , 會這樣實現 : (c 和 c++ 定義結構不同 )
type define struct MyStruct{
int mark;
(*fn) ();
} MyList;
然后你可以聲明這個結構數據 :
{1,A,
2,B
3,C
}
做一個循環 :
for(i=0;i<length;i++) {
if( 數據組 [i].mark == 傳入的值 ) ( 數據組 [i].*fn)();
}
簡單說 c/c++ 中將要被調用的涵數可以被保存起來 , 然后去訪問 , 調用 , 而 Java 中 , 我們無法將一個方法保存 , 除了直接調用 , 所以將要調用的方法用子類來實現 , 然后把這些子類實例保存起來 , 然后在這些子類的實現上調用方法 :
interface My{
void test();
}
class A implements My{
public void test(){
System.out.println(“A”):
}
}
class B implements My{
public void test(){
System.out.println(“B”):
}
}
class C implements My{
public void test(){
System.out.println(“C”):
}
}
class MyStruct {
int mark;
My m;
public MyStruct(int mark,My m){this.mark = amrk;this.m = m}
}
數組 :
{ new MyStruct(1,new A()),new MyStruct(2,new B()),new MyStruct(3,new C())}
for(xxxxxxxxx) if( 參數 == 數組 [i].mark) 數組 [i].m.test();
這樣把要調用的方法轉換為對象的保程不僅僅是可以對要調用的方法進行調度 , 而且可以把對象序列化后在另一臺機器上執行 , 這樣就把調用邊界從線程擴展到了機器 .
回到我們的例子 :
class Proxy implements Axman{
private final Scheduler scheduler;
private final Servant servant;
public Proxy(Scheduler scheduler,Servant servant){
this.scheduler = scheduler;
this.servant = servant;
}
public Result resultTest(int count,char c){
FutureResult futrue = new FutureResult();
this.scheduler.invoke(new ResultRequest(servant,futrue,count,c));
return futrue;
}
public void noResultTest(String str){
this.scheduler.invoke(new NoResultRequest(this.servant,str));
}
}
其中 scheduler 是管理對調用的調度 , servant 是真正的對方法的執行 :
Servant 就是去真實地實現方法 :
class Servant implements Axman{
public Result resultTest(int count,char c){
char[] buf = new char[count];
for(int i = 0;i < count;i++){
buf[i] = c;
try{
Thread.sleep(100);
}catch(Throwable t){}
}
return new RealResult(new String(buf));
}
public void noResultTest(String str){
try{
System.out.println("displayString :" + str);
Thread.sleep(10);
}catch(Throwable t){}
}
}
在 scheduler 將方法的調用 (invkoe) 和執行 (execute) 進行了分離 , 調用就是開始 ” 注冊 ” 方法到要執行的容器中 , 這樣就可以立即返回出來 . 真正執行多久就是 execute 的事了 , 就象一個人點燃爆竹的引信就跑了 , 至于那個爆竹什么時候爆炸就不是他能控制的了 .
public class Scheduler extends Thread {
private final ActivationQueue queue;
public Scheduler(ActivationQueue queue){
this.queue = queue;
}
public void invoke(MethodRequest request){
this.queue.putRequest(request);
}
public void run(){
while(true){
// 如果隊列中有請求線程 , 測開始執行請求
MethodRequest request = this.queue.takeRequest();
request.execute();
}
}
}
在 schetbduler 中只用一個隊列來保存代表方法和請求對象 , 實行簡單的 FIFO 調用 , 你要實更復雜的調度就要在這里重新實現 :
class ActivationQueue{
private static final int MAX_METHOD_REQUEST = 100;
private final MethodRequest[] requestQueue;
private int tail;
private int head;
private int count;
public ActivationQueue(){
this.requestQueue = new MethodRequest[MAX_METHOD_REQUEST];
this.head = this.count = this.tail = 0;
}
public synchronized void putRequest(MethodRequest request){
while(this.count >= this.requestQueue.length){
try {
this.wait();
}
catch (Throwable t) {}
}
this.requestQueue[this.tail] = request;
tail = (tail + 1)%this.requestQueue.length;
count ++ ;
this.notifyAll();
}
public synchronized MethodRequest takeRequest(){
while(this.count <= 0){
try {
this.wait();
}
catch (Throwable t) {}
}
MethodRequest request = this.requestQueue[this.head];
this.head = (this.head + 1) % this.requestQueue.length;
count --;
this.notifyAll();
return request;
}
}
為了將方法調用轉化為對象 , 我們通過實現 MethodRequestb 對象的 execute 方法來方法具體方法轉換成具體對象 :
abstract class MethodRequest{
protected final Servant servant;
}
本文的目的并不是介紹使用的什么技術,而是重點闡述其實現原理。
一、 異步和同步
講通俗點,異步就是不需要等當前執行的動作完成,就可以繼續執行后面的動作。
通常一個程序執行的順序是:從上到下,依次執行。后面的動作必須等前面動作執行完成以后方可執行。這就是和異步相對的一個概念——同步。
案例:
A、張三打電話給李四,讓李四幫忙寫份材料。
B、李四接到電話的時候,手上有自己的工作要處理,但他答應張三,忙完手上的工作后馬上幫張三寫好材料,并傳真給張三。
C、通完電話后,張三外出辦事。
說明:
張三給李四通完電話后,就出去辦事了,他并不需要等李四把材料寫好才外出。那么張三讓李四寫材料的消息就屬于異步消息。
相反,如果張三必須等李四把材料寫好才能外出辦事的話,那么這個消息就屬于同步消息了。
二、 異步的實現
傳統的程序執行代碼都是從上到下,一條一條執行的。
但生活中有很多情況并不是這樣,以上的案例中,如果李四需要幾個小時以后才能幫張三寫好材料的話,那張三就必須等幾個小時,這樣張三可能會崩潰或者抓狂。
這種一條龍似的處理,顯示不太合理。
可以使用以下辦法來處理這種問題:
張三找王五去給李四打電話,等李四寫好材料后,由王五轉交給張三。這樣張三就可以外出辦其他的事情了。
問題得到了合理的解決,之前張三一條線的工作,由張三和王五兩條線來完成了,兩邊同時進行,彼此不耽誤。
三、 計算機語言的實現
辦法有了,如何用程序來模擬實現呢?
A、以前由一個線程來處理的工作,可以通過新增一個線程來達到異步的目的。這也就是JAVA中的多線程技術。
B、最后李四寫好的材料必須交給張三,以做他用。這就是回調。
回調你可以這樣來理解:
A發送消息給B,B處理好A要求的事情后,將結果返回給A,A再對B返回的結果來做進一步的處理。
四、 Java代碼的實現
A、 回調的實現
Java代碼
tb
public interface CallBack {
public void execute(Object... objects );
}
public interface CallBack { public void execute(Object... objects ); }
Java是面向對象的語言,因此回調函數就變成了回調接口。
B、 消息的發送者
Javatb代碼
public class Local implements CallBack,Runnable{
private Remote remote;
private String message;
public Local(Remote remote, String message) {
super();
this.remote = remote;
this.message = message;
}
public void sendMessage()
{
System.out.println(Thread.currentThread().getName());
Thread thread = new Thread(this);
thread.start();
System.out.println("Message has been sent by Local~!");
}
public void execute(Object... objects