Java多線程經典例題


1、建立三個線程,A線程打印10次A,B線程打印10次B,C線程打印10次C,要求線程同時運行,交替打印10次ABC

   首先使用Java多線程,使用Object.wait()和Object.notify()來對對象釋放和喚醒操作。先創建三個對象鎖a、b、c,每個打印線程需要獲取前一個對象和自身對象才可以執行打印操作,否則等待。打印完后,立即釋放自身對象及前一個對象,喚醒等待自身對象的線程。為了避免JVM調用線程的時間片輪轉時間小於一個打印線程所需的時間,也就是說為了避免打印線程在還沒來得及釋放對象時,CPU寫換到其他線程引起其他結果,在創建線程時,需讓主線程sleep一下。

public class ABCThreadTest {

    /**
     * @param args
     * @throws InterruptedException 
     */
    public static void main(String[] args) throws InterruptedException {
        Object a = new Object();     
        Object b = new Object();     
        Object c = new Object();     
        MyThreadPrinter pa = new MyThreadPrinter("A", c, a);     
        MyThreadPrinter pb = new MyThreadPrinter("B", a, b);     
        MyThreadPrinter pc = new MyThreadPrinter("C", b, c);     
             
        new Thread(pa).start();  
        Thread.sleep(120);
        new Thread(pb).start();  
        Thread.sleep(120);
        new Thread(pc).start();
        Thread.sleep(120);
    }

}

class MyThreadPrinter  implements Runnable{
    private String name;     
    private Object prev;     
    private Object self;     
    
    MyThreadPrinter (String name, Object prev, Object self) {     
        this.name = name;     
        this.prev = prev;     
        this.self = self;     
    }     
    
    @Override    
    public void run() {     
        int count = 10;     
        while (count > 0) {     
            synchronized (prev) {     
                synchronized (self) {     
                    System.out.print(name);     
                    count--;    
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    self.notify();     
                }     
                try {     
                    if(count>0) prev.wait();     
                } catch (InterruptedException e) {     
                    e.printStackTrace();     
                }     
            }     
        }  
    } 
}
View Code

2、建立一個線程,子線程循環5次,主線程循環10次,一共執行10次

  在主線程main函數內新建一個子線程,執行Business中的sub方法,然后主線程執行Business中的main方法,sub方法與main方法通過變量bool實行同步。 

//子線程循環5次,主線程循環10次,如此循環5次,好像是空中網的筆試題
public class ThreadCircle {
    public static void main(String[] args) {  
        final Business business = new Business();  
        new Thread(new Runnable() {  
            @Override  
            public void run() {  
                threadExecute(business, "sub");  
            }  
        }).start();  
        threadExecute(business, "main");  
    }     
    public static void threadExecute(Business business, String threadType) {  
        for(int i = 0; i < 5; i++) {  
            try {  
                if("main".equals(threadType)) {  
                    business.main(i);  
                } else {  
                    business.sub(i);  
                }  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
}

class Business {  
    private boolean bool = true;  
    public synchronized void main(int loop) throws InterruptedException {  
        while(bool) {  
            this.wait();  
        }  
        for(int i = 0; i < 10; i++) {  
            System.out.println("main thread seq of " + i + ", loop of " + loop);  
        }  
        bool = true;  
        this.notify();  
    }     
    public synchronized void sub(int loop) throws InterruptedException {  
        while(!bool) {  
            this.wait();  
        }  
        for(int i = 0; i < 5; i++) {  
            System.out.println("sub thread seq of " + i + ", loop of " + loop);  
        }  
        bool = false;  
        this.notify();  
    }  
}  
//此處wait時用while而不是用if,官方也推薦用while,因為在線程wait后,線程有可能被假喚醒,用while的話,假喚醒還會繼續檢測bool是否符合要求
View Code

 


免責聲明!

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



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