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(); } } }