【Java面试题】30 子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。
题目如下:
子线程循环10次,接着主线程循环100,接着又回到子线程循环10次, 接着再回到主线程又循环100,如此循环50次
思路如下:
子线程语主线程为互斥,可用SYNCHRONIZED。很容易想到如下代码
package concurrent; public class theFirstIdea{ /** * @param args */ public static void main(String[] args) { new Thread(//子线程 new Runnable(){ public void run(){ for(int i=1;i<=50;i++){ synchronized(theFirstIdea.class){ for(int j=1;j<=10;j++){ System.out.println("sub thread: "+i+",loop: "+j); } } } } } ).start(); new Thread(//主线程 new Runnable(){ public void run(){ for(int i=1;i<=50;i++){ synchronized(theFirstIdea.class){ for(int j=1;j<=100;j++){ System.out.println("main thread: "+i+",loop: "+j); } } } } } ).start(); } }
由于运行结果很长(有5500行),所以在Eclipse 编译器无法全部看到,或看到的并不是最终运行结果。所以可以在Run -- Run configuration -- Common --勾选File,点击File System.选择到你想保存运行结果的地方,比如桌面,命名为1.txt. 此时桌面将会生产一个名为1.txt的文件,再次运行程序后,运行结果将保存到此文件中。便于查看。
查看后发现,基本达到要求,但并没有交替执行子线程和主线程。
而且上述代码不好,没有体现Java 的高类聚性,最好能将共同数据或共同方法归为同一类,即编写一个类来存放两个线程,便于修改。代码如下
package concurrent; public class theFirstIdea{ /** * @param args */ public static void main(String[] args) { final MyThread threads=new MyThread(); new Thread(//子线程 new Runnable(){ public void run(){ for(int i=1;i<=50;i++){ threads.subThread(i); } } } ).start(); for(int i=1;i<=50;i++){ threads.mainThread(i); } } } class MyThread{ public synchronized void subThread(int i){ for(int j=1;j<=10;j++){ System.out.println("sub thread: "+i+",loop: "+j); } } public synchronized void mainThread(int i){ for(int j=1;j<=10;j++){ System.out.println("main thread: "+i+",loop: "+j); } } }
要让他们交替进行,可用信号量控制,并用wait ,notify 进行线程间通信。易得
//子线程循环10次,接着主线程循环100,接着又回到子线程循环10次, //接着再回到主线程又循环100,如此循环50次,请写出程序。 public class ThreadTest{ public static void main(String[] args) { final MyThread threads=new MyThread(); new Thread( new Runnable(){ public void run(){ for(int i=1;i<=50;i++){ threads.subThread(i); } } } ).start(); new Thread(new Runnable(){ public void run(){ for(int i=1;i<=50;i++){ threads.mainThread(i); } } }).start(); } } class MyThread{ boolean bShouldSub=true;//标志子线程方法是否被调用 public synchronized void subThread(int i){ if(!bShouldSub){//若子线程没被调用,即主线程正在运行,所以等待 try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } for(int j=1;j<=10;j++){ System.out.println("sub thread :"+i+",loop : "+j); } bShouldSub=false;//子线程运行完毕 this.notify();//唤醒其他线程,即主线程 } public synchronized void mainThread(int i){ if(bShouldSub){//若子线程正在被调用,所以等待 try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } for(int j=1;j<=100;j++){ System.out.println("main thread :"+i+",loop : "+j); } bShouldSub=true;//主线程调用完毕 this.notify();//唤醒子线程 } }
转自:http://blog.csdn.net/carlosli/article/details/8738960