多線程編程題


 一 當多個線程需要協同完成一件事時,可以加鎖+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(){

            @Override
            public void run() {
                // TODO Auto-generated method stub
                for(int i = 0; i < 26; i++){
                    my.printNum();
                }
            }
            
        }).start();
        new Thread(new Runnable(){

            @Override
            public void run() {
                // TODO Auto-generated method stub
                for(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(){

            @Override
            public void run() {
                // TODO Auto-generated method stub
                for(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(){
            @Override
            public void run() {
                // TODO Auto-generated method stub
                for(int i = 0 ; i<10 ; i++)
                    ob.printA();
            }
            
        }).start();
        new Thread(new Runnable(){
            @Override
            public void run() {
                // TODO Auto-generated method stub
                for(int i = 0 ; i<10 ; i++)
                    ob.printB();
            }
            
        }).start();
        new Thread(new Runnable(){
            @Override
            public void run() {
                // TODO Auto-generated method stub
                for(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個程序的思路都一樣,都是定義一個對象,將方法都同步,每個方法都用一個線程啟動,對象之間有個全局變量,線程通過全局變量的設置來控制線程執行順序。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM