Showing posts with label Thread.. Show all posts
Showing posts with label Thread.. Show all posts

Friday, December 18, 2015

[Java] Hàm Join trong Java

Hàm Join được sử dụng để giữ cho quá trình thực thi của hàm đang chạy không bị gián đoạn bởi các thread khác, nói một cách khác nếu một thead đang chạy các thread khác sẽ phải chờ cho đến khi thread đó thực thi xong.
Tạo sao lại sử dụng hàm Join.
Trong một chương trình Java thường có nhiều hơn một thread,trong đó có main thread - có chức năng khởi tạo và kích hoạt để chạy các thread khác, tuy nhiên các main thread không đảm bảo các thread thực thi và kết thúc theo đúng thứ tự mà chúng đã được khởi chạy. Hãy xem ví dụ sau:
1. Khi không sử dụng hàm Join.
Ở đây có 3 thread th1, th2, th3. Mặc dù các thread được khởi chạy theo thứ tự th1>th2>th3 nhưng kết thúc thực thi của 3 thread trên không theo thứ tự th1>th2>th3. Ở mỗi thời điển chạy chương trình có thể nhận được các kết quả khác nhau.
public class JoinExample {
 public static void main(String[]args){
  Thread th1 = new Thread(new MyThread(),"th1");
  Thread th2 = new Thread(new MyThread(),"th2");
  Thread th3 = new Thread(new MyThread(),"th3");
  th1.start();
  th2.start();
  th3.start();
 }
}
class MyThread implements Runnable {
 public void run() {
  Thread t = Thread.currentThread();
  System.out.println("Bắt đầu thread: " + t.getName());
  try{
   Thread.sleep(4000);
  }catch(InterruptedException e){
   e.printStackTrace();
  }
  System.out.println("Kết thúc thread:" + t.getName());
 }
}
Output:
Bắt đầu thread: th1
Bắt đầu thread: th3
Bắt đầu thread: th2
Kết thúc thread:th3
Kết thúc thread:th1
Kết thúc thread:th2
2. Khi sử dụng hàm Join
Câu hỏi đưa ra là: Làm thế nào để các thread thực thi và kết thúc theo đúng thứ tự mà chúng được khởi chạy. Câu trả lời là: Sử dụng hàm Join sẵn có của Java. Giả sử thứ tự của các thread là: thread1 chạy trước, sau đó là thread2, thread3 chạy sau cùng.
Chương trình cài đặt sử dụng hàm Join như sau:
public class JoinExample {
 public static void main(String[]args){
  Thread th1 = new Thread(new MyThread(),"th1");
  Thread th2 = new Thread(new MyThread(),"th2");
  Thread th3 = new Thread(new MyThread(),"th3");
  //khởi chạy thread 1.
  th1.start();
  try {
   th1.join();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  //khởi chạy thread 2.
  th2.start();
  try {
   th2.join();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  //khởi chạy thread 3.
  th3.start();
  try {
   th3.join();
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
}
class MyThread implements Runnable {
 public void run() {
  Thread t = Thread.currentThread();
  System.out.println("Bắt đầu thread: " + t.getName());
  try{
   Thread.sleep(4000);
  }catch(InterruptedException e){
   e.printStackTrace();
  }
  System.out.println("Kết thúc thread:" + t.getName());
 }
}
Khi chạy chương trình trên, ta sẽ thấy kết quả in ra mà hình theo thứ tự  th1>th2>th3
Output:
Bắt đầu thread: th1
Kết thúc thread:th1
Bắt đầu thread: th2
Kết thúc thread:th2
Bắt đầu thread: th3
Kết thúc thread:th3
Khi so sánh với chương trình cài đặt không sử dụng hàm Join, thread2, thread3, chưa khởi chạy ngay được gọi bằng lệnh th2.start(), th3.start() , thead2 và thread3 đã đợi cho đến khi thread1 thực thi xong mới khởi chạy. Tương tự khi thread2 chạy thì thread3 vẫn phải đợi cho đến khi thread2 thực thi xong. Do đó mà kết quả in ra màn hình theo đúng thứ tự th1>th2>th3 mà chúng đã được khởi chạy.

[Java] Có thể khởi chạy Thread 2 lần không ?

Có thể khởi  chạy Thread 2 lần không ? Câu trả lời là không. Một thread khi đã khởi chạy thì nó không thể được khởi chạy lại. Nếu gọi khởi chạy thread lần thứ 2 Java sẽ ném ra một exception IllegalThreadStateException. Hãy xem ví dụ sau:
public class ThreadTwiceExample implements Runnable {
   public void run(){  
 Thread t = Thread.currentThread();
        System.out.println(t.getName()+" đang thực thi.");
      
   }  
   public static void main(String args[]){  
 Thread th1 = new Thread(new ThreadTwiceExample(), "thread1"); 
 th1.start();  
 th1.start();  
   } 
}
Khi chạy chương trình trên sẽ có thông báo lỗi như sau:
Exception in thread "main" thread1 đang thực thi.
java.lang.IllegalThreadStateException
 at java.lang.Thread.start(Unknown Source)
 at ThreadTwiceExample.main(ThreadTwiceExample.java:10)
Nhìn vào kết quả của chương trình trên phương thức run đã được gọi khi lệnh sau được thực thi:
th1.start();
Nhưng Java ném ra một lỗi khi phương thức trên được gọi đến lần thứ 2.