一 当多个线程需要协同完成一件事时,可以加锁+wait,notify一起完成。
1.写两个线程,一个线程打印1~52,另一个线程打印A~Z,打印顺序是12A34B...5152Z;
思路分析,一个线程打印数字,每次打印两个数字,26次打印完,另一个线程打印字母,也是26次打印完;可以创建两个方法,一个方法打印数字,一个打印字母;还有创建一个全局变量用来控制具体执行的是哪个线程;每个方法都被执行26次。
public class TwoThread {public static void main(String args[]){MyObject1 my = new MyObject1();new Thread(new Runnable(){@Overridepublic void run() {// TODO Auto-generated method stubfor(int i = 0; i < 26; i++){my.printNum();}}}).start();new Thread(new Runnable(){@Overridepublic void run() {// TODO Auto-generated method stubfor(int i = 0; i < 26; i++){my.printA();}}}).start();} } class MyObject1{private static boolean flag = true ;public int count = 1;public synchronized void printNum(){while(flag == false){try {this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}}System.out.print((2*count-1));System.out.print(2*count);flag = false;this.notify();}public synchronized void printA(){while(flag == true){try {this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}}System.out.print((char)(count+'A'-1));count++;flag = true;this.notify();} }
2.子线程循环10次,主线程循环100次,然后子线程循环10次,主线程循环100次,这样循环50次;
思路:跟上面那个一样,也是synchornized+wait,notify方法;难点在于主线程的启动不需要start方法,因为程序的入口是main方法,在执行这个程序的时候,主线程已经启动了;
public class SubMain {public static void main(String args[]){MyObject2 m = new MyObject2();new Thread(new Runnable(){@Overridepublic void run() {// TODO Auto-generated method stubfor(int i = 0; i<5; i++)m.sub();}}).start();for(int i = 0; i<5; i++)m.main1();} }class MyObject2{private boolean flag = true;//flag是true时执行sub方法,flag是false时执行main1方法public synchronized void sub(){while(flag == false){ //如果flag==false,说明另一个线程拥有该对象的锁,调用sub的方法被阻塞,直到另一个线程释放锁,唤醒该线程。try {this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}}for(int i = 0 ; i<10; i++){System.out.print("s");}System.out.println(); flag = false;this.notify();}public synchronized void main1(){while(flag == true){try {this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}}for(int i = 0 ; i<100; i++){System.out.print("m");}System.out.println(); flag = true;this.notify();}}
3.编写一个程序,启动三个线程,三个线程的ID分别是A,B,C;,每个线程将自己的ID值在屏幕上打印5遍,打印顺序是ABCABC...
public class ThreeThread extends Thread {public static void main(String[] args) {MyObject ob = new MyObject();new Thread(new Runnable(){@Overridepublic void run() {// TODO Auto-generated method stubfor(int i = 0 ; i<10 ; i++)ob.printA();}}).start();new Thread(new Runnable(){@Overridepublic void run() {// TODO Auto-generated method stubfor(int i = 0 ; i<10 ; i++)ob.printB();}}).start();new Thread(new Runnable(){@Overridepublic void run() {// TODO Auto-generated method stubfor(int i = 0 ; i<10 ; i++)ob.printC();}}).start();}}class MyObject {private int flag = 1;public synchronized void printA(){while(flag != 1){try {this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}}System.out.print("A");flag = 2;this.notifyAll();}public synchronized void printC(){while(flag != 3){try {this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}}System.out.println("C");flag = 1;this.notifyAll();}public synchronized void printB(){while(flag != 2){try {this.wait();} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}}System.out.print("B");flag = 3;this.notifyAll();}}
总结,这3个程序的思路都一样,都是定义一个对象,将方法都同步,每个方法都用一个线程启动,对象之间有个全局变量,线程通过全局变量的设置来控制线程执行顺序。