Java多線程理解

1、理論概念java

進程與線程多線程

進程(Process)是計算機中的程序關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位。併發

線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程本身基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),可是它可與同屬一個進程的其餘的線程共享進程所擁有的所有資源.ide

進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不一樣執行路徑。線程有本身的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等於整個進程死掉,因此多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行而且又要共享某些變量的併發操做,只能用線程,不能用進程。this

 

2、線程的Java實現spa

目前實現java線程有2種方式,繼承Thread類和實現Runnable接口,重寫run方法。線程

一、實現Runnable接口3d

實現 Runnable的接口的好處是實現變量的共享,多個線程使用同一個Runable對象,如上代碼塊中的成員變量j:code

package src;

/**
 * 
 * @author Shawn Wang
 * 
 */
public class MyThread implements Runnable {
    private int j = 100;

    @Override
    public void run() {
        while (true) {
            if (j > 0) {
                System.out.println(Thread.currentThread().getName() + "-- num:"
                        + j--);
            } else {
                break;
            }
        }
    }

    public static void main(String[] args) {
        MyThread mt = new MyThread();
        Thread thread1 = new Thread(mt);
        Thread thread2 = new Thread(mt);
        Thread thread3 = new Thread(mt);
        thread1.start();
        thread2.start();
        thread3.start();
    }
}
View Code

輸出結果:對象

Thread-1-- num:100
Thread-3-- num:98
Thread-2-- num:99
Thread-2-- num:95
Thread-3-- num:96
Thread-1-- num:97
Thread-1-- num:92
Thread-1-- num:91
Thread-3-- num:93
Thread-3-- num:89
Thread-3-- num:88
Thread-2-- num:94
Thread-2-- num:86
Thread-2-- num:85
Thread-2-- num:84
Thread-3-- num:87
Thread-3-- num:82
Thread-1-- num:90
Thread-1-- num:80
Thread-3-- num:81
Thread-3-- num:78
Thread-3-- num:77
Thread-3-- num:76
Thread-3-- num:75
Thread-3-- num:74
Thread-2-- num:83
Thread-2-- num:72
Thread-2-- num:71
Thread-2-- num:70
Thread-3-- num:73
Thread-1-- num:79
Thread-3-- num:68
Thread-3-- num:66
Thread-3-- num:65
Thread-2-- num:69
Thread-2-- num:63
Thread-2-- num:62
Thread-2-- num:61
Thread-2-- num:60
Thread-2-- num:59
Thread-2-- num:58
Thread-2-- num:57
Thread-2-- num:56
Thread-2-- num:55
Thread-2-- num:54
Thread-2-- num:53
Thread-2-- num:52
Thread-3-- num:64
Thread-1-- num:67
Thread-3-- num:50
Thread-2-- num:51
Thread-3-- num:48
Thread-1-- num:49
Thread-3-- num:46
Thread-2-- num:47
Thread-3-- num:44
Thread-1-- num:45
Thread-3-- num:42
Thread-2-- num:43
Thread-3-- num:40
Thread-1-- num:41
Thread-3-- num:38
Thread-2-- num:39
Thread-3-- num:36
Thread-1-- num:37
Thread-3-- num:34
Thread-2-- num:35
Thread-3-- num:32
Thread-1-- num:33
Thread-3-- num:30
Thread-2-- num:31
Thread-3-- num:28
Thread-1-- num:29
Thread-3-- num:26
Thread-2-- num:27
Thread-3-- num:24
Thread-1-- num:25
Thread-3-- num:22
Thread-2-- num:23
Thread-3-- num:20
Thread-1-- num:21
Thread-3-- num:18
Thread-2-- num:19
Thread-3-- num:16
Thread-1-- num:17
Thread-3-- num:14
Thread-2-- num:15
Thread-3-- num:12
Thread-1-- num:13
Thread-3-- num:10
Thread-2-- num:11
Thread-3-- num:8
Thread-1-- num:9
Thread-3-- num:6
Thread-2-- num:7
Thread-3-- num:4
Thread-1-- num:5
Thread-3-- num:2
Thread-2-- num:3
Thread-1-- num:1
result

二、繼承Thread類

package src;

public class ThreadClient extends Thread {

    public ThreadClient(String name) {
        super(name);
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i <= 10; i++) {
            System.out.println(currentThread().getName() + ":" + i);
        }
    }
   
    public static void main(String[] args) {
        ThreadClient thread1 = new ThreadClient("thread1");
        ThreadClient thread2 = new ThreadClient("thread1");
        ThreadClient thread3 = new ThreadClient("thread1");
        thread1.start();
        thread2.start();
        thread3.start();
    }

}
View Code

輸出結果

thread1:0
thread1:1
thread1:0
thread1:1
thread1:0
thread1:1
thread1:2
thread1:3
thread1:4
thread1:5
thread1:6
thread1:2
thread1:2
thread1:3
thread1:4
thread1:3
thread1:4
thread1:5
thread1:6
thread1:7
thread1:7
thread1:8
thread1:9
thread1:10
thread1:5
thread1:6
thread1:7
thread1:8
thread1:9
thread1:8
thread1:9
thread1:10
thread1:10
result

疑問:

爲何要重寫 run方法?

run方法時存儲線程所要運行的代碼,不能在直接調用run方法,須要經過start方法來調用。

3、線程同步

場景:若是線程進行了sleep 操做時,其餘線程對共享變量作了改變,會形成數據不一樣步問題。

package src;

/**
 * 
 * @author Shawn Wang
 * 
 */
public class MyThread implements Runnable {
    private int j = 100;

    @Override
    public void run() {
        while (true) {
            if (j > 0) {
                try {
                    Thread.sleep(1000);// 當前線程休眠1秒
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "-- num:"
                        + j--);
            } else {
                break;
            }
        }
    }

    public static void main(String[] args) {
        MyThread mt = new MyThread();
        Thread thread1 = new Thread(mt);
        Thread thread2 = new Thread(mt);
        Thread thread3 = new Thread(mt);
        thread1.start();
        thread2.start();
        thread3.start();
    }
}
View Code

輸出結果:

Thread-1-- num:100
Thread-2-- num:99
Thread-3-- num:98
Thread-1-- num:97
Thread-3-- num:95
Thread-2-- num:96
Thread-1-- num:94
Thread-2-- num:92
Thread-3-- num:93
Thread-3-- num:91
Thread-2-- num:90
Thread-1-- num:90
Thread-3-- num:89
Thread-2-- num:88
Thread-1-- num:87
Thread-3-- num:86
Thread-2-- num:85
Thread-1-- num:85
Thread-3-- num:84
Thread-2-- num:83
Thread-1-- num:82
Thread-3-- num:81
Thread-1-- num:80
Thread-2-- num:80
Thread-3-- num:79
Thread-2-- num:77
Thread-1-- num:78
Thread-3-- num:76
Thread-2-- num:75
Thread-1-- num:74
Thread-2-- num:73
Thread-3-- num:71
Thread-1-- num:72
Thread-2-- num:70
Thread-1-- num:69
Thread-3-- num:69
Thread-2-- num:68
Thread-3-- num:66
Thread-1-- num:67
Thread-2-- num:65
Thread-1-- num:64
Thread-3-- num:64
Thread-2-- num:63
Thread-1-- num:62
Thread-3-- num:61
Thread-2-- num:60
Thread-3-- num:58
Thread-1-- num:59
Thread-2-- num:57
Thread-1-- num:56
Thread-3-- num:56
Thread-2-- num:55
Thread-1-- num:54
Thread-3-- num:54
Thread-2-- num:53
Thread-3-- num:52
Thread-1-- num:52
Thread-3-- num:51
Thread-2-- num:50
Thread-1-- num:51
Thread-3-- num:49
Thread-1-- num:48
Thread-2-- num:48
Thread-3-- num:47
Thread-1-- num:46
Thread-2-- num:45
Thread-1-- num:44
Thread-2-- num:42
Thread-3-- num:43
Thread-3-- num:40
Thread-1-- num:39
Thread-2-- num:41
Thread-2-- num:38
Thread-3-- num:37
Thread-1-- num:38
Thread-1-- num:36
Thread-2-- num:35
Thread-3-- num:36
Thread-1-- num:34
Thread-2-- num:33
Thread-3-- num:33
Thread-1-- num:32
Thread-3-- num:30
Thread-2-- num:31
Thread-1-- num:29
Thread-3-- num:29
Thread-2-- num:29
Thread-3-- num:28
Thread-1-- num:28
Thread-2-- num:28
Thread-1-- num:27
Thread-2-- num:26
Thread-3-- num:27
Thread-1-- num:25
Thread-2-- num:24
Thread-3-- num:24
Thread-1-- num:23
Thread-3-- num:22
Thread-2-- num:22
Thread-1-- num:21
Thread-3-- num:20
Thread-2-- num:20
Thread-1-- num:19
Thread-3-- num:18
Thread-2-- num:17
Thread-3-- num:16
Thread-1-- num:15
Thread-2-- num:14
Thread-2-- num:13
Thread-3-- num:12
Thread-1-- num:13
Thread-2-- num:11
Thread-1-- num:10
Thread-3-- num:10
Thread-2-- num:9
Thread-1-- num:7
Thread-3-- num:8
Thread-2-- num:6
Thread-3-- num:5
Thread-1-- num:5
Thread-2-- num:4
Thread-3-- num:3
Thread-1-- num:2
Thread-2-- num:1
Thread-1-- num:0
Thread-3-- num:-1
result

出現了負數。

解決加上同步鎖synchronized

同步代碼塊的格式:
    synchronized(對象){
           須要被同步的代碼;
    } 

package src;

/**
 * 
 * @author Shawn Wang
 * 
 */
public class MyThread implements Runnable {
    private int j = 100;

    @Override
    public void run() {
        while (true) {
            synchronized (this) {
                if (j > 0) {
                    try {
                        Thread.sleep(1000);// 當前線程休眠1秒
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()
                            + "-- num:" + j--);
                } else {
                    break;
                }
            }
        }
    }

    public static void main(String[] args) {
        MyThread mt = new MyThread();
        Thread thread1 = new Thread(mt);
        Thread thread2 = new Thread(mt);
        Thread thread3 = new Thread(mt);
        thread1.start();
        thread2.start();
        thread3.start();
    }
}
View Code
相關文章
相關標籤/搜索