Java簡明教程 12.多線程(multithreading)

單線程和多線程html

關於它們的區別,zhihu上有一個回答,我認爲十分不錯,以下:java

1. 單進程單線程:一我的在一個桌子上吃菜。
2. 單進程多線程:多我的在同一個桌子上一塊兒吃菜。
3. 多進程單線程:多我的每一個人在本身的桌子上吃菜。

多線程的問題是多我的同時吃一道菜的時候容易發生爭搶.例如兩我的同時夾一個菜,一我的剛伸出筷子,結果伸到的時候已經被夾走菜了。此時就必須等一我的夾一口以後,在還給另一我的夾菜,也就是說資源共享就會發生衝突爭搶。

例子:
多線程:
瀏覽器瀏覽一個頁面,裏面有不少圖片,多線程,每一個線程下載一副圖片,他們至關於一個桌子上不一樣的菜。

多進程:
瀏覽器開了多個標籤瀏覽不一樣網站,多進程,由於他們至關於「不一樣的桌子」 

原文連接:http://www.zhihu.com/question/19901763

 

如何建立線程瀏覽器

方式1:多線程

MultiThreading.javadom

public class MultiThreading {
    public static void main(String[] args) {
        NewThread thread1 = new NewThread();
        NewThread thread2 = new NewThread();

        thread1.start();
        thread2.start();
    }   
}

class NewThread extends Thread {                                //繼承Thread類
    private static int num = 0;
    public NewThread() {
        super("THread:" + ++num);                               //經過Thraed的構造方法,初始化線程的名字
                                                                //public Thread(String name)
    }
    

    //重寫Thread的run()方法,而後經過Thread的start()方法調用run()方法,實現多線程
    @Override
    public void run() {
        while (true) {
            System.out.println(super.getName() + " is running~");//getName():獲取線程的名字
        }   
    }   
}

 

方式2:實現Runnable接口ide

MultiThreading2.java測試

public class MultiThreading2 {
    public static void main(String[] args) {
        Thread thread1 = new Thread(new NewThread("線程1"));
        Thread thread2 = new Thread(new NewThread("線程2"));

        thread1.start();
        thread2.start();
    }   
}

class NewThread implements Runnable {
    private String threadName = null;

    public NewThread(String threadName) {
        this.threadName = threadName;
    }   

    @Override
    public void run() {
        while (true) {
            System.out.println(this.threadName + " is running~");
        }
    }   
}

看下Thread類的構造方法,   "public Thread(Runnable target)", 不難懂上面那個小例子.網站

 

synchronizedthis

咱們考慮一個問題,若是一個桌子上有三我的(Person)在吃100個漢堡包(Hamburger), 當只有一個漢堡包的時候,其中的一我的判斷還有一個漢堡包(hamburgerNum > 0), 因此執行了eatHamburger()操做, 而另外一我的在這以前,也判斷了還有一個漢堡包(hamburgerNum > 0), 想要執行eatHamburger()操做的時候, 那個漢堡包已經被別人吃了, 那麼這個時候 (hamburgerNum--) 漢堡包的數量不就成了負數了嗎? 這明顯是不行的.spa

也就是說, "判斷和吃"這個兩個操做, 須要一我的一塊兒執行成功後, 才能讓另外一我的執行. 因此咱們須要把它們 "綁在一塊兒", 也就是"鎖"起來.這裏就不要用到 "syncronized"(同步)這個修飾符了

 

Test.java

public class Test {
    public static void main(String[] args) {
        Hamburger h = new Hamburger(100);
        Person p1 = new Person(h);
        Person p2 = new Person(h);
        Person p3 = new Person(h);

        p1.start();
        p2.start();
        p3.start();
    }   
}

class Person extends Thread {                       //繼承Thread類,重寫run()方法,經過調用Thread的start()方法,建立多個線程
    private int count = 0;                          //記錄這我的吃了多少個漢堡包
    private String name = "小明";
    private static int num = 0;                     //這裏須要使用static修飾
    private Hamburger hamburger = null;


    public Person(Hamburger hamburger) {
        this.hamburger = hamburger;
        this.name = this.name + (++num) + "號";
    }   

    @Override
    public void run() {
        while (true) {
            if (hamburger.eatHambergerNum()) {
                System.out.println(this.name + ": eat 1 Hamburger.");
                count++;
                try {
                    sleep((int)Math.random() * 100);                    //鄙人不明白爲何要這個句子?若是知道的請告知
                                                                        //或者,不須要這個句子?比人測試了,這個句子彷佛沒什麼做用
                                                                        //線程無論"sleep"不"sleep",都不會永遠分配給進程的霸佔cpu吧
                } catch(InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                break;
            }
        }
        System.out.println(this.name + ": " + count);
    }
}

class Hamburger {
    private int hamburgerNum = 0;

    public Hamburger(int num) {
        this.hamburgerNum = num;
    }


    //注意這裏使用了 "synchronized"修飾! "synchronized"也能夠修飾語句塊  用法: synchronized(對象) {}
    public synchronized boolean eatHambergerNum() {
        if (hamburgerNum > 0) {
            hamburgerNum--;
            return true;
        } else {
            return false;
        }
    }
}

 

參考:http://www.cnblogs.com/vamei/archive/2013/04/15/3000898.html

相關文章
相關標籤/搜索