1. 程式人生 > >java多執行緒:2 建立執行緒

java多執行緒:2 建立執行緒

如何建立一個多執行緒:

Java提供了java.lang.Thread類,這就是執行緒的定義類,包含了:執行緒的優先順序,執行緒id、執行緒狀態等執行緒的基本資訊。
通過Thread類的說明,可以知道建立執行緒的兩種方式:1 extends Thread類,2 implements Runnable介面

1 繼承Thread類

package com.thread;

public class ThreadCreate {
	public static void main(String[] args) {
		Thread t = new MyThread(new User("jkf"));
		t.start();
	}
}

class MyThread extends Thread{
	private User u;
	public MyThread(User u){
		this.u = u;
	}
	//重寫run方法
	public void run(){
		System.out.println("this is my Thread "+Thread.currentThread().getName());
		u.printName();
	}
}
class User{
	private String name;
	public User(String name){
		this.name=name;
	}
	public void printName(){
		System.out.println("this is "+name);
	}
}

輸出:
this is my Thread Thread-0
this is jkf


這是最簡單的方法,建立一個執行緒,通過重寫run方法,可以實現一些自定義的操作。
通過檢視Thread類的run方法,
public void run() {
  if (target != null) {
       target.run();
   }
}
還可以通過設定target物件,呼叫target的run方法,而private Runnable target; 是一個Runnable物件,而Thread提供這樣的建構函式。這就是建立多執行緒的第二種方式:實現Runnable介面

2 實現Runnable介面

package com.thread;

public class ThreadCreateRunnable {
	public static void main(String[] args) {
		Printer printer = new Printer(new User("jkf"));
		new Thread(printer).start();
	}
}

class Printer implements Runnable{
	private User u;
	public Printer(User u) {
		this.u=u;
	}
	public void run() {
		u.printName();		
	}
}
輸出內容:
this is jkf

通過提取print方法,通過Printer實現Runnable介面,實現執行緒的建立。

兩者的區別:

1 一個是通過繼承Thread類實現,一個通過實現Runnable介面實現,建議通過實現Runnable介面來建立執行緒,因為java類支援多實現,單繼承,如果繼承Thread類,那麼就不能繼承其他類了。

在Thread中,還有一個run(),通過上述的兩個例子,發現我們啟動執行緒都是通過start方法,而執行緒最後呼叫的仍然是run方法,那麼為什麼直接呼叫run方法,即t.run()。這涉及到jvm的底層,如果要建立一個執行緒那麼就必須通過start方法,這才是真正的生成一個新的執行緒。
例項:

public static void main(String[] args) {
	Thread t = new MyThread(new User("jkf"));
	t.run();
}
//把方法一種的t.start()修改為t.run(),輸出如下:
this is my Thread main
this is jkf

t.start()的輸出如下:
this is my Thread Thread-0
this is jkf

    兩者的主要區別就是this is my Thread Thread-0中Thread的名稱。
其中main表示的是主執行緒,即main執行緒,因為啟動main方法,那麼就是一個程序,一個程序對應一個執行緒,因此main執行緒就是最初的執行緒,而Thread-0是通過main建立的新執行緒。因此可以發現:t.start()建立了Thread-0,而t.run()卻仍然是主執行緒在呼叫,因此並不會建立新執行緒。
    因此啟動一個執行緒必須通過.start方法。

技巧

當我們建立一個執行緒時,最好給該執行緒使用一個有含義的名稱,這樣排查起來方便,看到執行緒名稱就知道是使用於什麼業務。

Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {

            }
        },"com.csdn.trade.createOrder");

小思考

前面說到,程序可以有多個執行緒,多個執行緒共用程序的記憶體等內容,思考:1個程序建立了3個執行緒,如果有一個執行緒記憶體溢位了,請問另外兩個執行緒怎麼樣了?

-----main方法執行上述方法前,請配置main方法的jvm引數,防止電腦跟著一起掛了
vm option:
-Xms1m -Xmx1m -XX:+HeapDumpOnOutOfMemoryError
同時為了好檢視,最好把輸出內容輸出到檔案中,這樣通過檔案進行檢視

public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<String[]> list = new ArrayList<>();
                while(true){
                    System.out.println("this is thread"+Thread.currentThread().getName()+",我要記憶體512");
                    String[] arr = new String[512];
                    list.add(arr);
                }

            }
        },"thread-512").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<String[]> list = new ArrayList<>();
                while(true){
                    System.out.println("this is thread"+Thread.currentThread().getName()+",我要記憶體2048");
                    String[] arr = new String[2048];
                    list.add(arr);
                }
            }
        },"thread-2048").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<String[]> list = new ArrayList<>();
                while(true){
                    System.out.println("this is thread"+Thread.currentThread().getName()+",我要記憶體1024");
                    String[] arr = new String[1024];
                    list.add(arr);
                }
            }
        },"thread-1024").start();
    }

--- 擷取一部分輸出內容

this is threadthread-1024,我要記憶體1024
this is threadthread-512,我要記憶體512
this is threadthread-1024,我要記憶體1024
this is threadthread-512,我要記憶體512
this is threadthread-512,我要記憶體512
this is threadthread-1024,我要記憶體1024
this is threadthread-512,我要記憶體512
this is threadthread-1024,我要記憶體1024
Exception in thread "thread-512" java.lang.OutOfMemoryError: Java heap space
	at cn.gov.zcy.vaccine.plan.dto.VaccinePlanProductsDto$1.run(VaccinePlanProductsDto.java:57)
	at java.lang.Thread.run(Thread.java:745)
this is threadthread-1024,我要記憶體1024
this is threadthread-1024,我要記憶體1024
this is threadthread-1024,我要記憶體1024
this is threadthread-1024,我

通過輸出內容,可以看到兩個執行緒都在執行,後來512的執行緒記憶體溢位,但是1024的執行緒繼續執行