Wait and Notify in java


Hôm nay mình xin giới thiệu đến với các bạn, về cách đơn giản trong việc chia sẻ công việc với nhau thông qua sử dụng Synchronization.

Công việc của mình như sau :

  1. ThreadA có tác vụ là xữ lý logic một vấn đề nào đó.
  2. ThreadB có tác vụ sử lý kết quả của logic trả về.
  3. Cả 2 thread đều hoạt động trên cùng 1 đối tượng.

Cách thức chương trình như sau :

Khi thread A xữ ly vấn đề. nếu vấn đề giải quyết thành công  nó sẻ rơi vào trạng thái chờ (wait) và nó kiu gọi (notify)  thằng threadB và nói rắng.

  • Ê thằng kia tao giải quyết xong vấn đề rồi mày thức dậy và sử dụng nó đi.

Thằng B nghe vậy chạy vào sử dụng kết quả trả về , thao tác gì đó , làm gì đó, v.v.v , và khi Thread B làm xong việc nó sẻ rơi vào trạng thái chờ và nói thằng threadA rằng.

  • Tao giải quyết xong rồi. Mày dậy làm việc tiếp đi.

Cứ như vậy công việc dùng chung 1 đối tượng sẻ dừng khi có một điều kiện nào đó .

Chúng ta xem bài viết dưới đây. Mình tạo ra threadA cho for i . nếu i chia hết 1000 thì mình sẻ gọi thằng thread B show value ra.

Đối tượng dùng chung : MyObject.java

package com.gcs.lockobject;

public class MyObject {
	private boolean valid = false;
	int i = 0;

	public synchronized void showValue(){
		try {			
			while(!isValid()){
				wait();
			}
			//pause();	
			System.out.println(i);
			setValid(false);
			notifyAll();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public synchronized void setValue(int value){
		try {
			while(isValid()){
				wait();
			}
			this.i = value;
			setValid(true);
			notifyAll();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public int getI() {
		return i;
	}

	public void setI(int i) {
		this.i = i;
	}

	public void pause(){
		try {
			Thread.sleep(50);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public boolean isValid() {
		return valid;
	}

	public void setValid(boolean valid) {
		this.valid = valid;
	}

}

Thread A : Xữ lý công việc Logic

package com.gcs.lockobject;

public class ThreadA implements Runnable{
	MyObject object;
	int i = 0;

	public ThreadA(MyObject object) {
		super();
		this.object = object;
	}

	public void run() {		
		for(int i = 1000; i <= 1000000; i++){
			if(i%1000 == 0){
				object.setValue(i);
			}
		}
		System.out.println("Thread A - Finished");
	}

}

Thread B : Xữ lý kết quả Logic Trả về


package com.gcs.lockobject;

public class ThreadB implements Runnable{
	MyObject obj;

	public ThreadB(MyObject obj) {
		this.obj = obj;
	}

	public void run() {		
		while(true){			
			obj.showValue();
			if(obj.i == 1000000)
				break;
		}
		System.out.println("Thread B - Finished");
	}

}

Hàm main của chúng ta

package com.gcs.lockobject;

public class MainTest {
	public static void main(String[] args) {
		MyObject object = new MyObject();

		Thread tA = new Thread(new ThreadA(object));
		Thread tB = new Thread(new ThreadB(object));

		tA.start();
		tB.start();
	}
}

Hy vọng giúp ích cho các bạn !!!!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: