Java多線程(1)

多線程的機制是指可以同時運行多個程序塊,是程序運行的效率變的更高。

一、兩種多線程的實現方式
如果要在類裏要激活線程,必須先做好下面兩個準備:
    1、線程必須擴展子Thread類,使自己成爲它的子類
    2、線程的處理必須編寫在run()方法裏面

繼承Thread類來實現多線程,其基本語法如下
class 類名稱 extends Thread{
       屬性...
       方法...
       修飾符 run(){
          other code
       }
}

範例1:
public class Test2 {
    public static void main(String args[]){
            TestThread t1 = new TestThread("A");
            TestThread t2 = new TestThread("B");
            t1.start();
            t2.start();
    }
}
class TestThread extends Thread{
    private String name;
    public TestThread(){
    }
    public TestThread(String name){
        this.name = name;
    }
    public void run(){
        for(int i=0;i<10;i++){
             System.out.println(name + " is running");
        }
    }
}

運行結果:
B is running
A is running
B is running
A is running
B is running
A is running
B is running
A is running
B is running
A is running
B is running
A is running
B is running
A is running
B is running
A is running
B is running
A is running
B is running
A is running

通過實現Runnable接口實現多線程,基本語法如下
class 類名稱 implements Runnable{
       屬性...
       方法...
       修飾符 run(){
          other code
       }
}

範例2:
public class Test3 {
    public static void main(String args[]){
            TestThread t1 = new TestThread("Thread A");
            Thread t11 = new Thread(t1);
            TestThread t2 = new TestThread("Thread B");
            Thread t22 = new Thread(t2);
            t11.start();
            t22.start();
    }
}
class TestThread implements Runnable{
    private String name;
    public TestThread(){
    }
    public TestThread(String name){
        this.name = name;
    }
    public void run(){
        for(int i=0;i<10;i++){
             System.out.println(name + " is running");
        }
    }
}
運行結果:
Thread B is running
Thread A is running
Thread B is running
Thread A is running
Thread B is running
Thread A is running
Thread B is running
Thread A is running
Thread B is running
Thread A is running
Thread B is running
Thread A is running
Thread B is running
Thread A is running
Thread B is running
Thread A is running
Thread B is running
Thread A is running
Thread B is running
Thread A is running

二、ThreadRunnable的區別:

如果一個類繼承Thread,則不適合資源共享。但是如果實現了Runable接口的話,則很容易的實現資源共享

範例1:
public class Test4 {
    public static void main(String args[]){
            TestThread t1 = new TestThread("A");
            TestThread t2 = new TestThread("B");
            t1.start();
            t2.start();
    }
}
class TestThread extends Thread{
    private String name;
    private int count = 5;
    public TestThread(){
    }
    public TestThread(String name){
        this.name = name;
    }
    public void run(){
        for(int i=0;i<10;i++){
             if(count > 0){
                 System.out.println("count = "+count--);
             }
        }
    }
}
運行結果:
count = 5
count = 5
count = 4
count = 4
count = 3
count = 3
count = 2
count = 2
count = 1
count = 1
沒有能夠實現資源共享,那麼用Ruannable接口呢,請看下面...........

範例2:
public class Test5 {
    public static void main(String args[]){
            TestThread t1 = new TestThread();
            Thread t11 = new Thread(t1,"1#");
            Thread t22 = new Thread(t1,"2#");
            t11.start();
            t22.start();
    }
}
class TestThread implements Runnable{
    private String name;
    private int count = 5;
    public TestThread(){
    }
    public TestThread(String name){
        this.name = name;
    }
    public void run(){
        for(int i=0;i<10;i++){
             if(count>0){
                 System.out.println(Thread.currentThread().getName()+" count = "+count--);
             }
        }
    }
}

運行結果:
2# count = 4
1# count = 5
2# count = 3
1# count = 2
2# count = 1
可以看出實現了資源共享

總結如下:

實現Runnable接口比繼承Thread類所具有的優勢:

   1):適合多個相同的程序代碼的線程去處理同一個資源

   2):可以避免java中的單繼承的限制

   3):增加程序的健壯性,代碼可以被多個線程共享,代碼和數據獨立。


三、線程中的一些操作方法

1、取得和設置線程的名稱
getName()
範例1:
public class Test {
     public static void main(String args[]){
         TestThread mTestThread = new TestThread();
         mTestThread.start();
         String ThreadName = Thread.currentThread().getName();
         System.out.println("Thread name is "+ThreadName);
     }
}
class TestThread extends Thread{
     public void run(){
         String ThreadName = Thread.currentThread().getName();
         System.out.println("TestThread name is "+ThreadName);
     }
}
運行結果:
Thread name is main
TestThread name is Thread-0

setName()
範例2:
public class Test {
     public static void main(String args[]){
         TestThread mTestThread = new TestThread();
         mTestThread.setName("NewName");
         mTestThread.start();
         String ThreadName = Thread.currentThread().getName();
         System.out.println("Thread name is "+ThreadName);
     }
}
class TestThread extends Thread{
     public void run(){
         String ThreadName = Thread.currentThread().getName();
         System.out.println("TestThread name is "+ThreadName);
     }
}
運行結果:
Thread name is main
TestThread name is NewName

2、判斷線程是否啓動
isAlive()
範例3:
public class Test {
     public static void main(String args[]){
         TestThread mTestThread = new TestThread();
         System.out.println("Before start the thread:isAlive = "+mTestThread.isAlive());
         mTestThread.start();
         System.out.println("After start the thread:isAlive = "+mTestThread.isAlive());
     }
}
class TestThread extends Thread{
     public void run(){
         String ThreadName = Thread.currentThread().getName();
         System.out.println("TestThread name is "+ThreadName);
     }
}

3、線程的強制執行
不使用join()
範例4:
public class Test {
     public static void main(String args[]){
         TestThread mTestThread = new TestThread();
         mTestThread.start();
         for(int i=0;i<5;i++){
             System.out.println("mai thread is running: "+i);
         }
     }
}
class TestThread extends Thread{
     public void run(){
         String ThreadName = Thread.currentThread().getName();
         for(int i=0;i<5;i++){
             System.out.println(ThreadName+" is runnging: "+i);
         }
     }
}

運行結果:
mai thread is running: 0
Thread-0 is runnging: 0
mai thread is running: 1
Thread-0 is runnging: 1
mai thread is running: 2
Thread-0 is runnging: 2
mai thread is running: 3
Thread-0 is runnging: 3
mai thread is running: 4
Thread-0 is runnging: 4

使用join()
範例5:
public class Test {
     public static void main(String args[]){
         TestThread mTestThread = new TestThread();
         mTestThread.start();
         for(int i=0;i<5;i++){
             if(i==2){
                try{
                   mTestThread.join();
                }catch(Exception e){
                }
             }
             System.out.println("mai thread is running: "+i);
         }
     }
}
class TestThread extends Thread{
     public void run(){
         String ThreadName = Thread.currentThread().getName();
         for(int i=0;i<5;i++){
             System.out.println(ThreadName+" is runnging: "+i);
         }
     }
}
運行結果:
mai thread is running: 0
Thread-0 is runnging: 0
mai thread is running: 1
Thread-0 is runnging: 1
Thread-0 is runnging: 2
Thread-0 is runnging: 3
Thread-0 is runnging: 4
mai thread is running: 2
mai thread is running: 3
mai thread is running: 4
可以看到執行完join()之後,就會一直執行Thread-0

4、線程休眠
使用sleep(long millions)來進行休眠
範例6:
import java.util.Date;
import java.text.SimpleDateFormat;
public class Test {
     public static void main(String args[]){
         TestThread mTestThread = new TestThread();
         mTestThread.start();
     }
}
class TestThread extends Thread{
     public void run(){
         String ThreadName = Thread.currentThread().getName();
         SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         System.out.println(df.format(new Date()));
         for(int i=0;i<5;i++){
             try{
                Thread.sleep(3000);
             }catch(Exception e){
                e.printStackTrace();
             }
             System.out.println(ThreadName+" is runnging: "+i);
             System.out.println(df.format(new Date()));
         }
     }
}

運行結果:每隔3秒輸出一個打印
2014-05-09 11:27:51
Thread-0 is runnging: 0
2014-05-09 11:27:54
Thread-0 is runnging: 1
2014-05-09 11:27:57
Thread-0 is runnging: 2
2014-05-09 11:28:00
Thread-0 is runnging: 3
2014-05-09 11:28:03
Thread-0 is runnging: 4
2014-05-09 11:28:06

5、線程中斷
使用interrupt()方法來中斷
範例7:
public class Test {
     public static void main(String args[]){
         TestThread mTestThread = new TestThread();
         mTestThread.start();
         try{
           mTestThread.sleep(2000);
         }catch(Exception e){
                e.printStackTrace();
         }
         mTestThread.interrupt();
     }
}
class TestThread extends Thread{
     public void run(){
         String ThreadName = Thread.currentThread().getName();
             try{
                Thread.sleep(10000);
                System.out.println("The thread finish sleep");
             }catch(Exception e){
                System.out.println("Sleep is interrupted");
                return;
             }
         System.out.println("The thread finish normally");
     }
}
運行結果:
Sleep is interrupted


6、後臺線程
對Java程序來說,只要還有一個前臺線程在運行,這個進程就不會結束,如果一個進程中只有後臺線程在運行,這個進程就會結束。前臺線程是相對後臺線程而言的。什麼樣的線程是後臺線程呢?如果某個線程對象在啓(調用start()方法)動之前調用了setDaemon(true)方法,這個線程就變成了後臺線程。
範例8:
public class Test {
     public static void main(String args[]){
         TestThread mTestThread = new TestThread();
         TestThread2 mTestThread2 = new TestThread2();
         mTestThread.setDaemon(true);
         mTestThread.start();
         mTestThread2.start();
     }
}
class TestThread extends Thread{
     public void run(){
         String ThreadName = Thread.currentThread().getName();
         while(true){
             System.out.println(ThreadName+" is running");
         }
     }
}
class TestThread2 extends Thread{
     public void run(){
         String ThreadName = Thread.currentThread().getName();
         for(int i=0;i<5;i++){
             System.out.println(ThreadName+" is running");
         }
     }
}
在TestThread中的run()中使用了死循環,如果不設置setDaemon(true)方法,那麼該程序將無線循環執行下去,如果使用該方法設爲後臺進程,則運行結果如下:
Thread-0 is running
Thread-1 is running
Thread-0 is running
Thread-1 is running
Thread-0 is running
Thread-1 is running
Thread-0 is running
Thread-1 is running
Thread-0 is running
Thread-1 is running
Thread-0 is running
Thread-0 is running
Thread-0 is running
Thread-0 is running
從以上結果我們可以看到,隨着TestThread2的結束,TestThread也會結束。

7、線程的優先級
  使用setPriority()設置優先級
public class Test {
     public static void main(String args[]){
         Thread mTestThread1 = new Thread(new TestThread(),"A");
         Thread mTestThread2 = new Thread(new TestThread(),"B");
         Thread mTestThread3 = new Thread(new TestThread(),"C");
         mTestThread1.setPriority(1);
         mTestThread1.setPriority(2);
         mTestThread1.setPriority(3);
         mTestThread1.start();
         mTestThread2.start();
         mTestThread3.start();
     }
}
class TestThread implements Runnable{
     public void run(){
         String ThreadName = Thread.currentThread().getName();
         for(int i=0;i<5;i++){
             System.out.println(ThreadName+" is running "+i);
         }
     }
}

運行結果:
C is running 0
A is running 0
B is running 0
A is running 1
C is running 1
A is running 2
B is running 1
B is running 2
A is running 3
C is running 2
A is running 4
B is running 3
C is running 3
B is running 4
C is running 4
並不是優先級越高就先執行,誰先執行還是取決於誰先去的CPU的資源。







發佈了35 篇原創文章 · 獲贊 10 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章