Thread

15 February 2017

ในการเขียนโปรแกรมในภาษา 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 นั้นจะใช้โค้ดและค่าที่อยู่ในตัวแปรร่วมกัน

Multithreaded 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

บทความนี้เป็นประโยชน์หรือไม่?Yes·No