练习:
实现两个线程交替打印1~100
思路:可以利用wait和notify方法实现,一个线程打印,打印完就释放对象锁,唤醒另一个线程打印,打印完释放对象锁,唤醒另一个线程打印,交替执行
class MyPrint implements Runnable{
int i = 1;
@Override
public void run() {
while (true){
synchronized (this){
this.notify();//在这里唤醒的目的是为保证拿到锁的线程只有一个 不
// 会立即释放锁 退出代码块才会释放锁
if (i <= 100 ){
System.out.println(Thread.currentThread().getName()+" "+i++);
}else {
break;
}
try {
this.wait();//打印过数据的线程等待 必须等到没打印过数字的拿到锁了才能唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class TurnPrint {
public static void main(String[] args) {
MyPrint print = new MyPrint();
Thread thread1 = new Thread(print,"A");
Thread thread2 = new Thread(print,"B");
thread1.start();
thread2.start();
}
}
实现创建N个线程交替打印0~100
通过锁class对象实现同步,若进入同步块的线程不是打印的正确对应关系,就让这个线程等待,如果是正确的就打印,打印后唤醒等待的线程,重新进入同步快,在同步块中选出应该打印的那个线程去执行任务
import java.util.Scanner;
public class TurnPrintN extends Thread{
private static int num = 0;
private static int count = 0;
private int id = 0;
public TurnPrintN(String name,int id){
super(name);
this.id = id;
}
@Override
public void run(){
synchronized (TurnPrintN.class){
while (true){
while (num % count != this.id){//这层循环是为了使得不对应id的线程不能获取全局锁
if (num > 100){
break;
}
try {
TurnPrintN.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//这时只有对应id的可以打印 打印后唤醒锁对象的class对象,进行下一次打印
if (num > 100){
break;
}
System.out.println(Thread.currentThread().getName()+" "+num);
num++;
TurnPrintN.class.notifyAll();
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("请输入线程个数:");
count = sc.nextInt();
for (int i = 0; i < count; i++) {
new TurnPrintN("Thread:"+i,i).start();
}
}
}