写2个线程,一个打印1-52,一个打印A-Z,打印顺序是12A34B。。。(采用同步代码块和同步方法两种同步方法)
1.同步方法
package Synchronized; /************************************同步方法****************************************/ public class PrintTest { public static void main(String[] args) { Print p = new Print(); Thread t1 = new PrintNumber(p); Thread t2 = new PrintWord(p); t1.start(); t2.start(); } } class PrintNumber extends Thread {//打印数字线程 private Print p; public PrintNumber(Print p) { this.p = p; } public void run() { for (int i = 0; i < 26; i++) { p.printNumber(); } } } class PrintWord extends Thread {//打印字母线程 private Print p; public PrintWord(Print p) { this.p = p; } public void run() { for (int i = 0; i < 26; i++) { p.printWord(); } } } class Print { //同步监视器是Print类 private int i = 1; private char j = 'A'; public Print() { } public synchronized void printNumber() {//同步方法 System.out.print(String.valueOf(i) + String.valueOf(i + 1)); i += 2; notifyAll(); //先唤醒其他进程,再阻塞本进程,如果顺序颠倒了,进程阻塞后不能再唤醒其他进程 try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void printWord() { System.out.print(j); j++; notifyAll(); try { if (j <= 'Z')//输出Z之后就不用再等待了。 { wait(); } } catch (InterruptedException e) { e.printStackTrace(); } } }
2.同步代码块package threaddemo;
/** * <写两个线程,一个线程打印1-52,另一个线程打印字母A-Z。打印 顺序为12A34B56C……5152Z> * */
/*****************************************同步代码块*********************************************/ public class ThreadDemo { // 测试 public static void main(String[] args) throws Exception { Object obj = new Object(); // 启动两个线程 Thread1 t1 = new Thread1(obj); Thread2 t2 = new Thread2(obj); t1.start(); t2.start(); } } // 一个线程打印1-52 class Thread1 extends Thread { private Object obj; public Thread1(Object obj) { this.obj = obj; } public void run() { synchronized (obj) { // 打印1-52 for (int i = 1; i < 53; i++) { System.out.print(i + " "); if (i % 2 == 0) { // 不能忘了 唤醒其它线程 obj.notifyAll(); try { obj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } } // 另一个线程打印字母A-Z class Thread2 extends Thread { private Object obj; public Thread2(Object obj) { this.obj = obj; } public void run() { synchronized (obj) //同步监视器是obj类,同步代码块是写在run方法里面的。 { // 打印A-Z for (int i = 0; i < 26; i++) { System.out.print((char)('A' + i) + " "); // 不能忘了 唤醒其它线程 obj.notifyAll(); try { // 最后一个就不要等了 if (i != 25) { obj.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } } } } }
下面是我后来写的。自习区分一下,因为主程序只有两个线程相互交替,所以是没有必要设置flag的。只有很多进程交互的时候,才有必要设置flag,并且我是通过flag来判断切换进程的,所以循环次数是52次,而不是26次。
public class test1 { public static void main(String[] args) { Print p = new Print(); new PrintNumber(p).start(); new PrintWord(p).start(); } } class Print { private boolean flag = false; public int num = 1; public char chr = 'A'; public synchronized void printNumber() { try { if(flag) { if(num <= 52) { wait(); } } else { System.out.print(num); System.out.print(num + 1); num += 2; flag = true; notify(); } } catch(InterruptedException ie) { ie.printStackTrace(); } } public synchronized void printWord() { try { if(!flag) { if(chr <= 'Z') { wait(); } } else { System.out.print(chr); chr += 1; flag = false; notify(); } } catch(InterruptedException ie) { ie.printStackTrace(); } } } class PrintNumber extends Thread { Print p; PrintNumber(Print p) { this.p = p; } public void run() { for(int i = 0; i < 52; i ++) { p.printNumber(); } } } class PrintWord extends Thread { Print p; PrintWord(Print p) { this.p = p; } public void run() { for(int i = 0; i < 52; i ++) { p.printWord(); } } }
实现Runnable接口
public class test2 { public static void main(String[] args) { Print p = new Print(); new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub for(int i = 0; i < 26; i ++) { p.printNum(); } } }).start(); new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub for(int i = 0; i < 26; i ++) { p.printWord(); } } }).start(); } } class Print { char chr = 'A'; int num = 1; public synchronized void printNum() { System.out.print(num); System.out.print(num + 1); num += 2; notify(); try{ wait(); } catch(InterruptedException ie) { ie.printStackTrace(); } } public synchronized void printWord() { System.out.print(chr); chr += 1; notify(); try{ if(chr <= 'Z') wait(); } catch(InterruptedException ie) { ie.printStackTrace(); } } }