Java多线程实现同步——wait()和notify()实现

要求:子线程循环5次,接着主线程循环10次,接着又回到子线程。如此循环50次。

实现以上要求的时候,除了直白的面向过程的实现,可以考虑面向对象的写法。

根据高内聚的原装,将子线程和主线程的操作都封装一起。

通过wait()和notify()进行同步。

1class Business { 2 private boolean shouldSub = true; 3 public synchronized void sub(int k) { 4 if (shouldSub) { 5 for (int i=0 ; i<5 ; i++) { 6 System.out.println("sub thread inner of " + i + " ,outer " + k); 7 } 8 shouldSub = false; 9 this.notifyAll(); 10 } else { 11 try { 12 this.wait(); 13 } catch (InterruptedException e) { 14 e.printStackTrace(); 15 } 16 } 17 } 18 19 public synchronized void main(int k) { 20 if (!shouldSub) { 21 for (int i=0 ; i<10 ; i++) { 22 System.out.println("main thread inner of " + i + " ,outer " + k); 23 } 24 shouldSub = true; 25 this.notifyAll(); 26 } else { 27 try { 28 this.wait(); 29 } catch (InterruptedException e) { 30 e.printStackTrace(); 31 } 32 } 33 } 34} 35 36public class TraditionalThreadCommucation { 37 38 public static void main(String[] args) { 39 40 final Business business = new Business(); 41 new Thread(new Runnable() { 42 @Override 43 public void run() { 44 for (int k=0; k<50 ;k++){ 45 business.sub(k); 46 } 47 } 48 }).start(); 49 50 new Thread(new Runnable() { 51 @Override 52 public void run() { 53 for (int k=0; k<50 ;k++){ 54 business.main(k); 55 } 56 } 57 }).start(); 58 } 59}

根据以上的设计思路,我们来解另一道题:

一个文件中有10000个数,用Java实现一个多线程程序将这个10000个数输出到5个不用文件中(不要求输出到每个文件中的数量相同)。要求启动10个线程,两两一组,分为5组。每组两个线程分别将文件中的奇数和偶数输出到该组对应的一个文件中,需要偶数线程每打印10个偶数以后,就将奇数线程打印10个奇数,如此交替进行。同时需要记录输出进度,每完成1000个数就在控制台中打印当前完成数量,并在所有线程结束后,在控制台打印”Done”.

1import java.io.BufferedReader; 2import java.io.File; 3import java.io.FileReader; 4import java.io.FileWriter; 5import java.io.PrintWriter; 6import java.util.Random; 7 8public class MyPrintByThread { 9 10 public static void main(String[] args) { 11 try { 12 PrintWriter pw = new PrintWriter(new FileWriter(new File("input.txt")),true); 13 Random random = new Random(); 14 for (int i=0 ; i<10000 ; i++) { 15 pw.print(Math.abs(random.nextInt()%100) + " "); 16 } 17 pw.flush(); 18 pw.close(); 19 20 BufferedReader reader = new BufferedReader(new FileReader("input.txt")); 21 String str = reader.readLine(); 22 reader.close(); 23 24 String[] strs = str.split(" "); 25 int j=0; 26 for (int i=0 ; i<5 ;i++) { 27 int records[] = new int[2000]; 28 for (int k=0 ; k<2000 ; k++) { 29 records[k] = Integer.parseInt(strs[j]); 30 j++; 31 } 32 PrintWriter writer = new PrintWriter(new FileWriter(new File("output"+i+".txt")),true); 33 final Business business = new Business(writer, records); 34 35 new Thread(new Runnable() { 36 @Override 37 public void run() { 38 business.printEven(); 39 } 40 }); 41 42 new Thread(new Runnable() { 43 @Override 44 public void run() { 45 business.printOdd(); 46 } 47 }); 48 } 49 } catch (Exception e) { 50 e.printStackTrace(); 51 } 52 } 53} 54 55class Business { 56 57 private boolean shouldEven = true; 58 private int[] subRecords; 59 private PrintWriter pw; 60 private int evenPointer = 0; 61 private int oddPointer = 0; 62 63 public Business(PrintWriter pw,int[] subRecords) { 64 this.pw = pw; 65 this.subRecords = subRecords; 66 } 67 68 public synchronized void printEven() { 69 if (shouldEven) { 70 if (evenPointer <= subRecords.length) { 71 for (int i=0 ; i<10 ;) { 72 if (subRecords[evenPointer] % 2 == 0) { 73 pw.print(subRecords[evenPointer] + " "); 74 75 if (evenPointer % 1000 == 0) 76 System.out.println("已经打印:" + evenPointer); 77 i++; 78 }  79 evenPointer++; 80 } 81 } 82 shouldEven = false; 83 this.notify(); 84 } else { 85 try { 86 this.wait(); 87 } catch (InterruptedException e) { 88 e.printStackTrace(); 89 } 90 } 91 } 92 93 public synchronized void printOdd() { 94 if (!shouldEven) { 95 if (oddPointer <= subRecords.length) { 96 for (int i=0 ; i<10 ;) { 97 if (subRecords[oddPointer] % 2 != 0) { 98 pw.print(subRecords[oddPointer] + " "); 99 100 if (evenPointer % 1000 == 0) 101 System.out.println("已经打印:" + oddPointer); 102 i++; 103 }  104 oddPointer++; 105 } 106 } 107 shouldEven = true; 108 this.notify(); 109 } else { 110 try { 111 this.wait(); 112 } catch (InterruptedException e) { 113 e.printStackTrace(); 114 } 115 } 116 } 117}

代码未经过测试,热心的朋友可以给我留言,支出修改的地方。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

多线程面试

多线程篇1.为什么要使用线程池tex避免频繁地创建和销毁线程,达到线程对象的重用。另外,使用线程池还可以根据项目灵活地控制并发的数目。2.java中如何获取到线程dump文件tex死循环、死锁、阻

4、jstack查看线程栈信息

1、介绍利用jps、top、jstack命令找到进程中耗时最大的线程,以及线程状态等等,同时最后还可以显示出死锁的线程查找:FoundoneJavaleveldeadlock即可1、jps获得进程号!(https://oscimg.oschina.net/oscnet/da00a309fa6

探索JAVA并发

\sleep/wait/notify/notifyAll分别有什么作用?它们的区别是什么?wait时为什么要放在循环里而不能直接用if?简介首先对几个相关的方法做个简单解释,Object中有几个用于线程同步的方法:wait、notify、notifyAll。publicclassObject{public