Giả sử ta có 2 luồng cùng hiển thị lần lượt thông tin trên màn hình tại cùng vị trí. Chương trình có dạng như sau:
import java.applet.Applet; import java.awt.Graphics;
public class Display extends Applet { public void init() {
Graphics g = getGraphics();
Thread1 t1 = new Thread1(g); Thread2 t2 = new Thread2(g); t1.start(); t2.start(); } } Luồng 1:
public class Thread1 extends Thread { private Graphics g;
public Thread1(Graphics g){ this.g = g;
101
}
public void run(){ while(true){
g.drawString("Thread 1",50,50); try {
Thread.sleep(5000);
} catch (InterruptedException ex) { }
} }
}
Luồng 2:
public class Thread2 extends Thread { private Graphics g;
public Thread2(Graphics g){ this.g = g;
}
public void run(){ while(true){
g.drawString("Thread 2",50,50); try {
Thread.sleep(5000);
} catch (InterruptedException ex) { }
} }
}
Kết quả hiển thị như sau:
Trong chương trình trên chúng ta thấy hai luồng cùng sử dụng màn hình tại một thời điểm mà không có sự trao đổi qua lại để định khoảng thời gian sử dụng cho mỗi luồng. Vì vậy, thông báo trên màn hình được hiển thị chồng lấn lên nhau. Để giải quyết vấn đề này, chúng ta phải định ra một khoảng thời gian cho mỗi luồng. Khi luồng nào hết thời gian thì sẽ thông báo cho các luồng khác để biết. Cụ thể chương trình như sau:
102
Luồng 1:
public class Thread1 extends Thread { private Graphics g;
private SharedScreen s;
public Thread1(Graphics g, SharedScreen s){ this.g = g;
this.s = s; }
public void run(){ while(true){ s.request(); g.drawString("Thread 1",50,50); s.relinquish(); try { Thread.sleep(5000);
} catch (InterruptedException ex) { }
} }
}
Luồng 2:
public class Thread2 extends Thread { private Graphics g;
private SharedScreen s;
public Thread2(Graphics g,SharedScreen s){ this.g = g;
this.s = s; }
public void run(){ while(true){ s.request(); g.drawString("Thread 2",50,50); s.relinquish(); try { Thread.sleep(5000);
} catch (InterruptedException ex) { }
} }
}
Lớp định thời và thông báo việc sử dụng màn hình:
public class SharedScreen {
private boolean inUse = false; private Graphics g;
SharedScreen(){
103
public synchronized void request(){ while(inUse)
try { wait();
} catch (InterruptedException ex) { }
inUse = true; }
public synchronized void relinquish(){ inUse = false;
notifyAll(); }
104
BÀI TẬP CHƯƠNG 6
Bài 1: Viết chương trình hiển thị hai luồng cùng truy cập tới một biến nguyên. Luồng
thứ nhất tăng giá trị của biến lên 1 đơn vị. Luồng thứ hai tăng giá trị của biến lên 2 đơn vị. Mỗi luồng thực hiện công việc 10 lần.
Bài 2: Viết chương trình hiển thị hai luồng. Luồng thứ nhất hiển thị một số ngẫu nhiên
trong khoảng từ 0 đến 10. Luồng thứ hai hiển thị giá trị bình phương của số ngẫu nhiên của luồng 1.
105