記錄一次回客科技有關線程的筆試題,三個線程加法和一個線程減法 ,延申的兩個線程交替執行

來源:互聯網
上載者:User

標籤:https   count   tps   url   線程   www.   void   cond   out   

今天去了回客科技 筆試了一波。很遺憾啊,腦袋有思路 但是還沒到手寫代碼很熟練的程度,基本功不到位。

第一道:線程的題:三個線程 +1 一個線程 -1 運算 。

看到網上還有四個線程的,兩個加法計算,兩個減法運算。基本的思路都是一樣的 ,注意看同步處理。

下面貼出代碼實現:

public class AddTest {    private static int i;    private static Object object = new Object();    public static void main(String[] args) {                    new Thread(() -> {            synchronized (object) {                i++;            }        }).start();        new Thread(() -> {            synchronized (object) {                i++;            }        }).start();        new Thread(() -> {            synchronized (object) {                i++;            }        }).start();        new Thread(() -> {            synchronized (object) {                i--;            }        }).start();
//這裡睡眠 等所有線程運行完畢 看最終的數值,2 try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(i); }}



 這裡引申出來了其他問題的思考

第1種:
synchronized void add 修飾普通方法 等同於
synchronized (this)
  public int i = 0;    public void add(String threadName) {        synchronized (this) {            i++;            System.out.println(threadName + "加法運算:" + i);        }    }//上面代碼等於如下代碼:   public synchronized void add(String threadName) {              i++;            System.out.println(threadName + "加法運算:" + i);          }

  

第2種:
synchronized static void add 修飾靜態方法 等同於
synchronized (*.class)

說明:以上兩種我分析為 synchornized 修飾普通方法和this 對應的是同一個執行個體對象。而修飾靜態方法和class 是對應的同一個類的 唯一的class對象。這個是我的理解,有錯誤之處請各位指正。在此謝過

第二道:
一個線程加一運算,一個線程做減法運算,多個線程同時交替運行(延申的)

第1種方法:使用Synchronized 實現
public class Count {    private int num = 0;    private boolean flag = false; // 標識    //加法    public synchronized void add() {        while (flag) {            try {                wait();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        this.num++; //加        System.out.println(Thread.currentThread().getName() + "........" + this.num);        this.flag = true; //設定標識為true        notifyAll(); //喚醒所有線上程池中凍結的線程,會把所有都喚醒    }    //減法    public synchronized void sub() {        while (!flag) {            try {                wait();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        this.num--; //減        System.out.println(Thread.currentThread().getName() + "........" + this.num);        this.flag = false; //設定標識為true        notifyAll(); //喚醒所有線上程池中凍結的線程,會把所有都喚醒    }}

 第2種 :使用Lock 鎖實現

 

public class CountLock {    private int num = 0;    private boolean flag = false; // 標識    Lock lock = new ReentrantLock(); // 鎖    Condition add = lock.newCondition(); // 加法鎖    Condition sub = lock.newCondition();// 減法鎖    public void add() {        lock.lock();// 鎖上        try {            while (flag) {  //迴圈判斷                add.await();            }            this.num++;            System.out.println(Thread.currentThread().getName() + "........" + this.num);            this.flag = true; // 設定標識            sub.signal(); // 喚醒指定線程        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            lock.unlock();        }    }    public void sub() {        lock.lock();// 鎖上        try {            while (!flag) {//迴圈判斷                sub.await();            }            this.num--;            System.out.println(Thread.currentThread().getName() + "........" + this.num);            this.flag = false; // 設定標識            add.signal(); // 喚醒指定線程        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            lock.unlock();        }    }}

  

調用的 main 方法:
    public static void main(String[] args) {        //Count c=new Count();        CountLock c=new CountLock();        Thread t1=new Thread(new Runnable() {            @Override            public void run() {                while (true) {                    c.add();                }            }        });        Thread t2=new Thread(new Runnable() {            @Override            public void run() {                while (true){                    c.sub();                }            }        });        t1.start();        t2.start();   //這裡感覺線程少可以再啟動 兩個t3或者t4 來驗證真實性    }

  

這裡延申的知識點參考部落格:
java synchronized修飾普通方法,修飾靜態方法,修飾代碼塊,修飾線程run方法 比較



記錄一次回客科技有關線程的筆試題,三個線程加法和一個線程減法 ,延申的兩個線程交替執行

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.