Archive for category thread
เคยเขียน Thread ไหม?
Posted by boysbee in java, programming, thread on 09/06/2011
ว่าจะเขียน blog นี้ตั้งแต่สองอาทิตย์ก่อนแต่งานมันเยอะ
วันนี้ว่างนิด ๆ เลยเกงานมาเขียน blog ซะหน่อย “เคยเขียน Thread ไหม?” มันก็เขียนยังงี้ครับ
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
public class ThreadTest {
@Test
public void testThread() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("normal thread : "
+ Thread.currentThread().getName());
sleep(1000);
}
});
thread.start();
}
private static void sleep(int value) {
try {
Thread.sleep(value);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
อันนี้คือการเขียน Thread โดยใส่ object runable เราอาจจะเรียก worker ก็ได้ เสร็จแล้วเราก็สั่งให้มันทำงานด้วย method start มันก็จะวิ่งเข้าไปทำงานใน statement ทีเขียนไว้ครับ หลังจากเรารู้วิธีการเขียน Thread แบบง่าย ๆ แล้วเรามาดูเรื่องถัดไปดีกว่า เพราะคำถามถัดมาที่ผมได้รับ “ถ้าเกิดมันมีหลาย ๆ file มันจะทันไหม?” แปลว่ากระบวนการทำงานของเราไม่ได้มีแค่งาน ๆ เดียวครับ มันอาจจะพร้อม ๆ กันต้องทำงานหลาย ๆ งานก็ได้ ทำไงดีละ?? ผมก็มองไปที่ Thread Pool ก่อน โชคดีผมเขียน java 1.6 ชีวิตมันเลยง่ายขึ้นมาหน่อยไม่ต้องเขียนตัวจัดการ pool เองมันก็มี class ที่ใช้จัดการเบื้องต้นมาให้เสร็จสรรพแล้ว
มันคือ class ไหนเหรอ?? ครับพระเอกของเรามันคือ class Executors,ExecutorService ครับลองดูวิธีการเขียนกันดีกว่า
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
public class ThreadTest {
@Test
public void testFixThreadPool() {
ExecutorService es = Executors.newFixedThreadPool(5);
long start = System.currentTimeMillis();
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("fix thread : "
+ Thread.currentThread().getName());
sleep(1000);
}
};
for (int i = 0; i < 10; i++) {
es.execute(task);
sleep(500); // 1
}
es.shutdown();
long stop = System.currentTimeMillis();
System.out.println("fix thread took: " + (stop - start));
}
@Test
public void testThreadCachePool() {
ExecutorService es = Executors.newCachedThreadPool();
long start = System.currentTimeMillis();
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("cache thread : "
+ Thread.currentThread().getName());
sleep(1000);
}
};
for (int i = 0; i < 10; i++) {
es.execute(task);
sleep(500); // 1
}
es.shutdown();
long stop = System.currentTimeMillis();
System.out.println("cache thread took: " + (stop - start));
}
@Test
public void testSingleThread() {
ExecutorService ec = Executors.newSingleThreadExecutor();
long start = System.currentTimeMillis();
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("single thread : "
+ Thread.currentThread().getName());
sleep(1000);
}
};
for (int i = 0; i < 10; i++) {
ec.execute(task);
}
ec.shutdown();
waitTenSeconds(ec);
long stop = System.currentTimeMillis();
System.out.println("single thread took: " + (stop - start));
}
private static void waitTenSeconds(ExecutorService ec) {
try {
ec.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static void sleep(int value) {
try {
Thread.sleep(value);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
เราจะเห็นได้ว่า Executors.newSingleThreadExecutor() นั้นทำงานช้าเพราะมันต้องเข้าไปทำงานที่ Thread เดียวกัน ตรงกันข้าม Executors.newCachedThreadPool() กลับทำงานเร็วกว่าใน loop เราจะสร้าง Thread เท่าที่ต้องการและไม่ต้องรอให้ Thread ก่อนหน้าทำงานเสร็จเหมือน SingleThread ครับ CachedThreadPool เนี่ยจะเป็นเช่นเดียวกับ FixedThreadPool ครับแต่ FixedThreadPool เราสามารถจำกัดจำนวนของ Thread ได้ครับการทำงานของมันจะ reues Thread ที่มีอยู่นำมาใช้งาน เป็นไงครับ java กับ thread pool ง่ายใช่มะ?