這個很簡單,先說一下實現的原理:利用 JavaScript實現表單的實時互動。 再簡單介紹實現的過程:先給<body>標簽的屬性onload屬性設置一個值,連接到相應的JavaScript函數,JavaScript函數將文本框中的內容通過innerHTML實時傳遞到對應ID的表格中的<td></td>標簽對中,便實現了你所要的效果。
少年阿賓那些青春的歲月 |
我現在是這樣的 我有三個文本框,我想每個里面瀏覽者一輸入文字,在表的表格里馬上就自動顯示出來這個文本框輸入的內容,有高手指教 這個很簡單,先說一下實現的原理:利用 JavaScript實現表單的實時互動。 再簡單介紹實現的過程:先給<body>標簽的屬性onload屬性設置一個值,連接到相應的JavaScript函數,JavaScript函數將文本框中的內容通過innerHTML實時傳遞到對應ID的表格中的<td></td>標簽對中,便實現了你所要的效果。 下面就給你寫下具體的代碼: (復制粘貼到一個TXT文檔中,將后綴名改為htm就可以) <script language="javascript"> function chk() { setTimeout("chk()",100); text1.innerHTML = form1.t1.value; text2.innerHTML = form1.t2.value; text3.innerHTML = form1.t3.value; } </script> <body onload="chk()"> <form name="form1"> <textarea name="t1"></textarea><br /> <textarea name="t2"></textarea><br /> <textarea name="t3"></textarea><br /> </form> <table border="1" width="200" style="border-collapse: collapse" bordercolor="#008000"> <tr height="100px"> <td id="text1"></td> </tr> <tr height="100px"> <td id="text2"></td> </tr> <tr height="100px"> <td id="text3"></td> </tr> </table> </body>
摘要: 1 ICE簡介1.1 簡介ICE(Internet Communications Engine)是一個中間件平臺。作為一個高性能的互聯網通信平臺,ICE包含了很多分層的服務和插件(Plug-ins),并且簡單、高效和強大。ICE當前支持C++、Java、C#、Visual... 閱讀全文
摘要: ModelDriven 為什么需要ModelDriven 所謂ModelDriven ,意思是直接把實體類當成頁面數據的收集對象。比如,有實體類User 如下: package cn.com.leadfar.struts2.actions; public class User { &nb... 閱讀全文
現在服務器端的應用程序幾乎都采用了“線程池”技術,這主要是為了提高系統效率。因為如果服務器對應每一個請求就創建一個線程的話,在很短的一段時間內就會產生很多創建和銷毀線程動作,導致服務器在創建和銷毀線程上花費的時間和消耗的系統資源要比花在處理實際的用戶請求的時間和資源更多。線程池就是為了盡量減少這種情況的發生。
下面我們來看看怎么用Java實現一個線程池。一個比較簡單的線程池至少應包含線程池管理器、工作線程、任務隊列、任務接口等部分。其中線程池管理器(ThreadPool Manager)的作用是創建、銷毀并管理線程池,將工作線程放入線程池中;工作線程是一個可以循環執行任務的線程,在沒有任務時進行等待;任務隊列的作用是提供一種緩沖機制,將沒有處理的任務放在任務隊列中;任務接口是每個任務必須實現的接口,主要用來規定任務的入口、任務執行完后的收尾工作、任務的執行狀態等,工作線程通過該接口調度任務的執行。 1.為什么要使用線程池 在java中,如果每個請求到達就創建一個新線程,開銷是相當大的。在實際使用中,服務器在創建和銷毀線程上花費的時間和消耗的系統資源都相當大,甚至可能要比在處理實際的用戶請求的時間和資源要多的多。除了創建和銷毀線程的開銷之外,活動的線程也需要消耗系統資源。如果在一個jvm里創建太多的線程,可能會使系統由于過度消耗內存或“切換過度”而導致系統資源不足。為了防止資源不足,服務器應用程序需要采取一些辦法來限制任何給定時刻處理的請求數目,盡可能減少創建和銷毀線程的次數,特別是一些資源耗費比較大的線程的創建和銷毀,盡量利用已有對象來進行服務,這就是“池化資源”技術產生的原因。 線程池主要用來解決線程生命周期開銷問題和資源不足問題。通過對多個任務重復使用線程,線程創建的開銷就被分攤到了多個任務上了,而且由于在請求到達時線程已經存在,所以消除了線程創建所帶來的延遲。這樣,就可以立即為請求服務,使用應用程序響應更快。另外,通過適當的調整線程中的線程數目可以防止出現資源不足的情況。 2.線程池的組成部分 一個比較簡單的線程池至少應包含線程池管理器、工作線程、任務列隊、任務接口等部分。其中線程池管理器的作用是創建、銷毀并管理線程池,將工作線程放入線程池中;工作線程是一個可以循環執行任務的線程,在沒有任務是進行等待;任務列隊的作用是提供一種緩沖機制,將沒有處理的任務放在任務列隊中;任務接口是每個任務必須實現的接口,主要用來規定任務的入口、任務執行完后的收尾工作、任務的執行狀態等,工作線程通過該接口調度任務的執行。 線程池管理器至少有下列功能:創建線程池,銷毀線程池,添加新任務。 工作線程是一個可以循環執行任務的線程,在沒有任務時將等待。 任務接口是為所有任務提供統一的接口,以便工作線程處理。任務接口主要規定了任務的入口,任務執行完后的收尾工作,任務的執行狀態等。 3.線程池適合應用的場合 當一個服務器接受到大量短小線程的請求時,使用線程池技術是非常合適的,它可以大大減少線程的創建和銷毀次數,提高服務器的工作效率。但是線程要求的運動時間比較長,即線程的運行時間比? ...... 在多線程大師Doug Lea的貢獻下,在JDK1.5中加入了許多對并發特性的支持,例如:線程池。 一、簡介 corePoolSize: 線程池維護線程的最少數量 如果此時線程池中的數量等于 corePoolSize,但是緩沖隊列 workQueue未滿,那么任務被放入緩沖隊列。 如果此時線程池中的數量大于corePoolSize,緩沖隊列workQueue滿,并且線程池中的數量小于maximumPoolSize,建新的線程來處理被添加的任務。 如果此時線程池中的數量大于corePoolSize,緩沖隊列workQueue滿,并且線程池中的數量等于maximumPoolSize,那么通過 handler所指定的策略來處理此任務。
//------------------------------------------------------------ //TestThreadPool.java
package com.abin.task; import java.io.Serializable; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class TestThreadPool { private static int produceTaskSleepTime = 2; private static int consumeTaskSleepTime = 2000; private static int produceTaskMaxNumber = 10; public static void main(String[] args) { // 構造一個線程池 ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3, TimeUnit.SECONDS, new ArrayBlockingQueue(3), new ThreadPoolExecutor.DiscardOldestPolicy()); for (int i = 1; i <= produceTaskMaxNumber; i++) { try { // 產生一個任務,并將其加入到線程池 String task = "task@ " + i; System.out.println("put " + task); threadPool.execute(new ThreadPoolTask(task)); // 便于觀察,等待一段時間 Thread.sleep(produceTaskSleepTime); } catch (Exception e) { e.printStackTrace(); } } }
/** * 線程池執行的任務 * @author hdpan */
package com.abin.task; import java.io.Serializable; /** public class ThreadPoolTask implements Runnable, Serializable { private static final long serialVersionUID = 0; // 保存任務所需要的數據 private Object threadPoolTaskData; ThreadPoolTask(Object tasks) { this.threadPoolTaskData = tasks; } public void run() { // 處理一個任務,這里的處理方式太簡單了,僅僅是一個打印語句 System.out.println("start .." + threadPoolTaskData); try { // //便于觀察,等待一段時間 Thread.sleep(consumeTaskSleepTime); } catch (Exception e) { e.printStackTrace(); } threadPoolTaskData = null; } public Object getTask() { return this.threadPoolTaskData; } }
2、一般來說任務除了處理方式外,還需要處理的數據,處理的數據通過構造方法傳給任務。 3、在這段程序中,main()方法相當于一個殘忍的領導,他派發出許多任務,丟給一個叫 threadPool的任勞任怨的小組來做。 這個小組里面隊員至少有兩個,如果他們兩個忙不過來,任務就被放到任務列表里面。 如果積壓的任務過多,多到任務列表都裝不下(超過3個)的時候,就雇傭新的隊員來幫忙。但是基于成本的考慮,不能雇傭太多的隊員,至多只能雇傭 4個。 如果四個隊員都在忙時,再有新的任務,這個小組就處理不了了,任務就會被通過一種策略來處理,我們的處理方式是不停的派發,直到接受這個任務為止(更殘忍!呵呵)。 因為隊員工作是需要成本的,如果工作很閑,閑到 3SECONDS都沒有新的任務了,那么有的隊員就會被解雇了,但是,為了小組的正常運轉,即使工作再閑,小組的隊員也不能少于兩個。 4、通過調整 produceTaskSleepTime和 consumeTaskSleepTime的大小來實現對派發任務和處理任務的速度的控制,改變這兩個值就可以觀察不同速率下程序的工作情況。 5、通過調整4中所指的數據,再加上調整任務丟棄策略,換上其他三種策略,就可以看出不同策略下的不同處理方式。 6、對于其他的使用方法,參看jdk的幫助,很容易理解和使用。 java.lang.Object
強烈建議程序員使用較為方便的
昨天開始研究java.util.concurrent,是出于線程安全的知識懂得不多,對自己寫的線程池沒有信心,所以就用了包里專家寫好的線程池。這個包的功能很強大。有興趣的朋友可以搜索了解更多的內容。 今天剛寫好了一段200行左右的代碼,拿出來跟大家分享我的學習經驗。初次實踐,不足之處,望能得到高手的指點。 功能說明:一個發送消息模塊將消息發送到消息隊列中,無需等待返回結果,發送模塊繼續執行其他任務。消息隊列中的指令由線程池中的線程來處理。使用一個Queue來存放線程池溢出時的任務。 TestDriver.java是一個驅動測試,sendMsg方法不間斷的向ThreadPoolManager發送數據。 public class TestDriver public void sendMsg( String msg ) public static void main( String[] args )
ThreadPoolManager類:是負責管理線程池的類。同時維護一個Queue和調度進程。 public class ThreadPoolManager // 線程池維護線程的最少數量 // 線程池維護線程的最大數量 // 線程池維護線程所允許的空閑時間 // 線程池所使用的緩沖隊列大小 // 消息緩沖隊列 // 訪問消息緩存的調度線程 final RejectedExecutionHandler handler = new RejectedExecutionHandler() // 管理數據庫訪問的線程池 // 調度線程池 final ScheduledFuture taskHandler = scheduler.scheduleAtFixedRate( public static ThreadPoolManager newInstance() private ThreadPoolManager(){} private boolean hasMoreAcquire() public void addLogMsg( String msg ) AccessDBThread類:線程池中工作的線程。 public class AccessDBThread implements Runnable public void setMsg( String msg ) public void run() }
ThreadPoolManager類:負責管理線程池,調用輪詢的線程來訪問字符串緩沖區的內容,維護緩沖區,當線程池溢出時拋出的Runnable任務被加入到字符緩沖區。
package com.abin.message.line; import java.util.LinkedList; import java.util.Queue; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Executors; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ThreadPoolManager { private static ThreadPoolManager tpm = new ThreadPoolManager(); // 線程池維護線程的最少數量 private final static int CORE_POOL_SIZE = 4; // 線程池維護線程的最大數量 private final static int MAX_POOL_SIZE = 10; // 線程池維護線程所允許的空閑時間 private final static int KEEP_ALIVE_TIME = 0; // 線程池所使用的緩沖隊列大小 private final static int WORK_QUEUE_SIZE = 10; // 消息緩沖隊列 Queue msgQueue = new LinkedList(); // 訪問消息緩存的調度線程 final Runnable accessBufferThread = new Runnable() { public void run() { // 查看是否有待定請求,如果有,則創建一個新的AccessDBThread,并添加到線程池中 if (hasMoreAcquire()) { String msg = (String) msgQueue.poll(); Runnable task = new AccessDBThread(msg); threadPool.execute(task); } } }; final RejectedExecutionHandler handler = new RejectedExecutionHandler() { public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { System.out.println(((AccessDBThread) r).getMsg() + "消息放入隊列中重新等待執行"); msgQueue.offer(((AccessDBThread) r).getMsg()); } }; // 管理數據庫訪問的線程池 final ThreadPoolExecutor threadPool = new ThreadPoolExecutor( CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new ArrayBlockingQueue(WORK_QUEUE_SIZE), this.handler); // 調度線程池 final ScheduledExecutorService scheduler = Executors .newScheduledThreadPool(1); final ScheduledFuture taskHandler = scheduler.scheduleAtFixedRate( accessBufferThread, 0, 1, TimeUnit.SECONDS); public static ThreadPoolManager newInstance() { return tpm; } private ThreadPoolManager() { } private boolean hasMoreAcquire() { return !msgQueue.isEmpty(); } public void addLogMsg(String msg) { Runnable task = new AccessDBThread(msg); threadPool.execute(task); } } package com.abin.message.line; public class AccessDBThread implements Runnable { private String msg; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public AccessDBThread() { super(); } public AccessDBThread(String msg) { this.msg = msg; } public void run() { // 向數據庫中添加Msg變量值 System.out.println("Added the message: " + msg + " into the Database"); } } package com.abin.message.line; public class TestDriver { ThreadPoolManager tpm = ThreadPoolManager.newInstance(); public void sendMsg(String msg) { tpm.addLogMsg(msg + "記錄一條日志 "); } public static void main(String[] args) { for (int i = 0; i < 100; i++) { new TestDriver().sendMsg(Integer.toString(i)); } } } package com.ibm.abin.util; import java.util.Random; /** |