Thread
ในการเขียนโปรแกรมในภาษา Java นั้นสนับสนุนการเขียนโปรแกรมแบบ Multithreading ซึ่งทำให้โปรแกรมสามารถทำงานควบคู่กันไปพร้อมกันๆ กันในแต่ละ Thread ได้ ทุกๆ Thread ในภาษา Java นั้นมีลำดับความคำคัญของ Thread โดยปกติเมื่อโปรแกรมในภาษา Java ทำงานนั้นจะมีอย่างน้อยหนึ่ง Thread ที่เป็น Thread ในการทำงานที่เรียกว่า Main thread ในบทนี้ เราจะแนะนำให้คุณรู้จักกับ Thread และความสำคัญในการทำไปพัฒนาโปรแกรม และตัวอย่างการใช้งานของ Thread ในภาษา Java
Thread คืออะไร
Thread คือส่วนของการประมวลผลชุดลำดับคำสั่งของโปรแกรมที่เล็กที่สุดที่สามารถจัดการโดยตัวจัดการ ซึ่งโดยปกติแล้วจะพบในระบบปฏิบัติการ การพัฒนาของ Thread และ Process นั้นแตกต่างกันในแต่ละระบบปฏิบัติการ แต่โดยส่วนมากแล้ว Thread นั้นเป็นส่วนประกอบของ Process Multiple threads นั้นสามารถพบได้ในหนึ่ง Process ที่ทำงานพร้อมๆ กันโดยการใช้งาน Resource ร่วมกัน เช่น หน่วยความจำ ในขณะที่ Process ที่ต่างกันนั้นจะไม่ใช้ Resource เหล่านี้ร่วมกัน สำหรับ Thread ของ Process นั้นจะใช้โค้ดและค่าที่อยู่ในตัวแปรร่วมกัน
ในการเขียนโปรแกรมนั้น โดยปกติโปรแกรมที่เราเขียนขึ้นจะเป็นแบบ Single threading program ในการที่จะใช้ประโยชน์จาก Thread นั้นโปรแกรมจะต้องเป็นแบบ Multithreading ซึ่งจะมีข้อได้เปรียบ เช่น มีการตอบสนองของโปรแกรมที่ดีกว่า การประมวลผลเร็วกว่า ใช้ทรัพยากรน้อยกว่า การใช้ประโยชน์จากระบบมากกว่า และการทำงานแบบขนาน เป็นต้น
การสร้าง Thread ในภาษา Java
ต่อไปมาดูตัวอย่างการสร้างและใช้งาน Thread ในภาษา Java ซึ่งในการสร้าง Thread นั้นจะมีอยู่สองวิธีด้วยกันคือการ Implement จาก Runnable Interfaces และการสืบทอดจากคลาส Thread
public class ThreadExample {
public static void main(String[] args){
Thread t1 = new Thread(new MyThread());
t1.start();
}
}
class MyThread implements Runnable {
@Override
public void run() {
System.out.println("Thread is running...");
}
}
ในตัวอย่าง เป็นการสร้าง Thread อย่าง่ายในภาษา Java โดยคลาส MyThread
เป็นคลาสการทำงานของ Thread ที่ Implement จาก Interfaces Runnable
และมี abstract เมธอด run()
เป็นเมธอดสำหรับกำหนดการทำงานของ Thread เพื่อให้ Thread ทำงาน เราสร้าง Thread ออบเจ็คจากคลาส Thread
และเริ่มต้นการทำงานของ Thread ด้วยเมธอด start()
public class ThreadExample {
public static void main(String[] args){
Thread t1 = new Thread(new MyThread());
t1.start();
}
}
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running...");
}
}
ในตัวอย่างก่อนหน้า เป็นการสร้าง Thread โดยการ Implement จาก Interfaces Runnable ในภาษา Java คุณสามารถสร้าง Thread ได้อีกแบบหนึ่งคือการสืบทอดจากคลาส Thread
และทำการ Override เมธอด run()
สำหรับการทำงานของ Thread เช่นเดิม และนำคลาสนี้ไปใช้งานกับคลาส Thread
เพื่อเริ่มต้นการทำงานของ Thread
การสร้าง Multi-threaded program
ต่อไปเป็นตัวอย่างของโปรแกรมแบบ Multiple thread ซึ่งจะเป็นโปรแกรมในการแสดงข้อความสวัสดีออกทางหน้าจอตามด้วยหมายเลขของ Thread ที่ทำงาน
public class ThreadExample {
public static void main(String[] args){
for (int i = 0; i < 4; i++) {
Thread t1 = new Thread(new HelloMessage(i + 1));
t1.start();
}
}
}
class HelloMessage implements Runnable {
public int threadNum;
public HelloMessage(int threadNum) {
this.threadNum = threadNum;
}
@Override
public void run() {
System.out.println("Hello from thread " + threadNum);
}
}
ในตัวอย่างเป็นโปรแกรมในการแสดงผลข้อความสวัสดี โดยคลาส HelloMessage
นั้น Implement มาจาก Interfaces Runnable และในคลาสนี้มีตัวแปร threadNum
สำหรับเก็บหมายเลขของ Thread
for (int i = 0; i < 4; i++) {
Thread t1 = new Thread(new HelloMessage(i + 1));
t1.start();
}
ในการทำงานของ Thread นั้นเราได้ใช้คำสั่ง For loop สำหรับสร้าง Thread 4 Thread และกำหนดหมายเลขให้กับ Thread โดยเริ่มจาก 0 ในการทำงานนั้น Thread แต่ละ Thread จะทำการแสดงข้อความ Hello ตามด้วยหมายเลข Thread ของมันเอง ซึ่งในการแสดงผลข้อความในแต่ละ Thread นี้เกิดขึ้นพร้อมๆ เพราะว่าการทำงานของ Thread นั้นเป็นแบบคู่ขนานกันไป
Hello from thread 1
Hello from thread 4
Hello from thread 3
Hello from thread 2
และนี่เป็นผลลัพธืการทำงานของโปรแกรม คุณจะเห็นว่าลำดับการทำงานของ Thread นั้นไม่เรียงจาก 1 ไป 4 เพราะว่า Thread นั้นทำงานแบบ Parallelism
Prime number Multithreading programming
ต่อไปเป็นตัวอย่างในการประยุกต์ใช้งานของการเขียนโปรแกรมแบบ Multithreading เพื่อเพิ่มประสิทธิภาพของโปรแกรมให้ทำงานได้เร็วขึ้น ซึ่งเราจะใช้ Thread สำหรับหาตัวเลขจำนวนเฉพาะในตัวเลข 1 - 100 และแสดงตัวเลขที่เป็นจำนวนเฉพาะออกมาทางหน้าจอโดยวิธี Multithreading programming
public class MultipleThreadExample {
public static void main(String[] args){
final int NUM_THREAD = 4;
for (int i = 0; i < NUM_THREAD; i++) {
Thread t1 = new Thread(new PrimeThread(i + 1));
t1.start();
}
}
}
class PrimeThread implements Runnable {
public int threadNum;
public static int number = 1;
public static int MAX_NUMBER = 100;
public PrimeThread(int threadNum) {
this.threadNum = threadNum;
}
@Override
public void run() {
while (true) {
int n = ++number;
if (n <= MAX_NUMBER) {
if(IsPrime(n)) {
System.out.println("Thread " + threadNum +
": " + n + " is prime number");
}
} else {
break;
}
}
}
public boolean IsPrime(int number) {
for (int i = 2; i < number; i++) {
if (number % i == 0 && i != number) return false;
}
return true;
}
}
ในตัวอย่าง เป็นโปรแกรมในการหาเลขจำนวนเฉพาะระหว่าง 1 - 100 และแสดงผลตัวเลขที่เป็นจำนวนเฉพาะออกทางหน้าจอ คลาส PrimeThread
เป็นคลาสของ Thread ที่ทำงานสำหรับกาเลขจำนวนเฉพาะ
ภายในคลาสเรามีตัวแปร static สองตัวคือ number
เป็นตัวแปรในการเพิ่มตัวเลขสำหรับหาจำนวนเฉพาะไปเรื่อยๆ จนถึง MAX_NUMBER
นั้นเป็นตัวเลขมากที่สุดสำหรับการทำงาน นั่นหมายความว่าทุก Thread มีการใช้งานตัวแปรเหล่านี้ร่วมกัน
@Override
public void run() {
while (true) {
int n = ++number;
if (n <= MAX_NUMBER) {
if(IsPrime(n)) {
System.out.println("Thread " + threadNum +
": " + n + " is prime number");
}
} else {
break;
}
}
}
ในเมธอด run()
เป็นการกำหนดส่วนการทำงานของโปรแกรม ซึ่งแต่ Thread อาจจะมีการหาตัวเลขจำนวนเฉพาะมากกว่า 1 ครั้งโดยการตรวจสอบด้วยตคำสั่ง If ในเงื่อนไข n <= MAX_NUMBER
และทุก Thread จะหยุดทำงานเมื่อเงื่อนไขนี้เป็นเท็จ หรือการหาของตัวเลขนั้นครบทั้ง 100 ตัวแล้วนั่นเอง
final int NUM_THREAD = 4;
for (int i = 0; i < NUM_THREAD; i++) {
Thread t1 = new Thread(new PrimeThread(i + 1));
t1.start();
}
นี่เป็นโปรแกรมหลักในการสร้าง Thread และเพื่อให้โปรแกรมทำงาน ตัวแปร NUM_THREAD
เป็นการกำหนดจำนวนของ Thread ที่ต้องการสร้างสำหรับทำงาน ในตัวอย่างเราได้สร้าง 4 Thread นั้นหมายความว่าแต่ละ Thread นั้นจะมีการทำงานโดยเฉลี่ยคนละ 25 ตัวเลข ซึ่งในอุดมคติแล้ว ถ้าหากการทำงานของการหาจำนวนเฉพาะของแต่ละตัวเลขนั้นเป็นอิสระต่อกัน การทำงานของโปรแกรมจะเร็วขึ้นเป็น 4 เท่า
แต่ในการทำงานจริง เราจะเป็นต้องวัดประสิทธิภาพการทำงานของระบบหรือเรียกว่า System utilization เพื่อหาจำนวน Thread ที่ให้ประสิทธิภาพสูงสุดของการทำงานในโปรแกรม ซึ่งเราจะไม่ได้กล่าวถึงในบทเรียนนี้
Thread 2: 2 is prime number
Thread 2: 5 is prime number
Thread 2: 7 is prime number
Thread 2: 11 is prime number
Thread 3: 13 is prime number
Thread 1: 3 is prime number
Thread 4: 23 is prime number
Thread 3: 19 is prime number
Thread 2: 17 is prime number
Thread 3: 37 is prime number
Thread 4: 31 is prime number
Thread 4: 47 is prime number
Thread 1: 29 is prime number
Thread 4: 53 is prime number
Thread 3: 43 is prime number
Thread 2: 41 is prime number
Thread 3: 67 is prime number
Thread 4: 61 is prime number
Thread 1: 59 is prime number
Thread 4: 79 is prime number
Thread 3: 73 is prime number
Thread 2: 71 is prime number
Thread 3: 97 is prime number
Thread 4: 89 is prime number
Thread 1: 83 is prime number
นี่เป็นผลลัพธ์การทำงานของโปรแกรมโดยการแสดงผลจำนวนประเฉพาะตั้งแต่ 1 - 100 คุณสามารถเปลี่ยนค่าในตัวแปร static number
และ MAX_NUMBER
สำหรับแสดงผลของจำนวนเฉพาะในระยะอื่นที่ต้องการ
ในบทนี้ คุณได้รู้จักกับ Thread และประโยชน์ของการนำ Thread ไปใช้ในการพัฒนาโปรแกรมเพื่อให้มีประสิทธิภาพมากขึ้น และตัวอย่างการเขียนโปรแกรมแบบ Multi-threading programming ในภาษา Java