多線程的實現

多線程

在講線程之前,我們應該先了解一下什麼是進程?

 

進程:系統可以進行獨立調配並且它是一個不可分割 獨立單元

例如(我們手機或者電腦後臺運行的軟件,客戶端等等,它們就是進程)

 

線程:線程是進程中一個獨立的單元,線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間

例如:(我們的電腦管家可以進行殺毒和清理垃圾,其中的殺毒和清理垃圾功能就可以看做事線程)

 

多線程:像上面所說的電腦管家,當我們同時執行清理垃圾和殺毒功能,雖然表面看起來是可以同步進行的,但實際不是同步進行的,只是每個線程在搶佔CPU的執行權,這就是多線程。

多線程的意義:爲了提高CPU的使用率,

線程之間都在搶佔CPU的執行權,而且多線程的執行是隨機的

 

要想實現多線程程序,需要開啓進程,開啓進程就需要創建系統資源,但是隻有c/c++可以創建資源,所我們我們可以在底層利用c創建好的系統資源來實現

 

併發和並行的區別:

併發是指同一個時間點,物理邏輯上的

並行指的是同一個時間段。

讓我們來看看多線程的實現:

首先我們需要創建一個子類去實現Thread類,並且要重寫該類的run方法

package com.westos.Thread;
 
public class MyThread extends Thread{


/*public MyThread(String name) {
super(name);
}*/
 
public void run() {
for(int x=0;x<100;x++) {
System.out.println(getName()+":"+x);
}
}
 
}

 

創建一個實現類去實現多線程,這是給線程設置名字的兩種方式:

package com.westos.Thread;
 
public class ThreadDome {
 
/**
 * @param args
 * 給線程設置名字的兩種方式
 * 使用方式1時:可以不在MyThread類中添加無參構造,因爲系統默認訪問無參構造
 * 當你使用第二種方式時,就必須要添加有參構造了,否則就會報錯
 */
public static void main(String[] args) {

//方式1:無參+setName()方法

//創建MyThread類對象

MyThread mt=new MyThread();
MyThread mt2=new MyThread();

//setName方法
mt.setName("迪麗熱巴");
mt2.setName("井傑");

//開始運行
mt.start();
mt2.start();

//方式2:直接MyThread類的有參構造

/*//創建MyThread類對象
 
MyThread mt=new MyThread("迪麗熱巴");
MyThread mt2=new MyThread("井傑");

//開始運行
mt.start();
mt2.start();
*/
}
}

 

線程的一些方法:

等待該線程終止

public final void join()throws InterruptedException等待該線程終止。

 

返回正在執行的線程:

public static Thread currentThread()返回對當前正在執行的線程對象的引用。

 

 

package com.westos.Thread01;
 
public class ThreadJoin extends Thread{
 
public void run() {
for(int x=0;x<100;x++) {
System.out.println(getName()+":"+x);
}
}
}

 

package com.westos.Thread01;
 
public class ThreadDome {
public static void main(String[] args) {
//創建三個ThreadJoin類對象
ThreadJoin tj=new ThreadJoin();
ThreadJoin tj2=new ThreadJoin();
ThreadJoin tj3=new ThreadJoin();

//設置名字
tj.setName("劉備");
tj2.setName("張飛");
tj3.setName("關羽");

tj.start();
//public final void join()throws InterruptedException等待該線程終止。
try {
tj.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

tj2.start();
tj3.start();
/*//public static Thread currentThread()返回對當前正在執行的線程對象的引用。
System.out.println(Thread.currentThread().getName());
運行的結果是:main(該方法返回的是正在執行的主線程,而tj和tj2是主線程的兩個子線程)
*/
}
 
}

 

暫停線程:

public static void yield()暫停當前正在執行的線程對象,並執行其他線程

package com.westos.Thread02;
 
public class Threadyield extends Thread{
 
public void run() {
for(int x=0;x<100;x++) {
System.out.println(getName()+":"+x);
}
//public static void yield()暫停當前正在執行的線程對象,並執行其他線程。
Thread.yield();
}
}

 

 

package com.westos.Thread02;
 
public class YieldDome {
 
public static void main(String[] args) {
//創建Threadyield類對象
Threadyield ty=new Threadyield();
Threadyield ty2=new Threadyield();

//設置名字
ty.setName("蜘蛛俠");
ty2.setName("鋼鐵俠");

//開始運行
ty.start();
ty2.start();
}
}

 

守護線程:

public final void setDaemon(boolean on)將該線程標記爲守護線程或用戶線程

 

package com.westos.Thread03;
 
public class ThreadsetDaemon extends Thread{
 
public void run() {
for(int x=0;x<100;x++) {
System.out.println(getName()+":"+x);
}
}
}

 

 

package com.westos.Thread03;
 
/**
 * @author 傑哥
 *調用setDaemon方法時,必須有主線程一起啓動,否則無法編譯
 */
public class setDaemonDome {

public static void main(String[] args) {

//創建ThreadsetDaemon類對象
ThreadsetDaemon td=new ThreadsetDaemon();
ThreadsetDaemon td2=new ThreadsetDaemon();

td.setName("雅妃");
td2.setName("美杜莎");

//public final void setDaemon(boolean on)將該線程標記爲守護線程或用戶線程。
//當正在運行的線程都是守護線程時,Java 虛擬機退出。 
//該方法必須在啓動線程前調用。 值爲true時表示正常
 
td.setDaemon(true);
td2.setDaemon(true);

//啓動線程
td.start();
td2.start();

Thread.currentThread().setName("蕭炎");
for(int i=0;i<5;i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
}

}
}

 

休眠:

public static void sleep(long millis) throws InterruptedException

在指定的毫秒數內讓當前正在執行的線程休眠(暫停執行),

package com.westos.Thread03;
 
/**
 * @author 傑哥
 *調用setDaemon方法時,必須有主線程一起啓動,否則無法編譯
 */
public class setDaemonDome {

public static void main(String[] args) {

//創建ThreadsetDaemon類對象
ThreadsetDaemon td=new ThreadsetDaemon();
ThreadsetDaemon td2=new ThreadsetDaemon();

td.setName("雅妃");
td2.setName("美杜莎");

//public final void setDaemon(boolean on)將該線程標記爲守護線程或用戶線程。
//當正在運行的線程都是守護線程時,Java 虛擬機退出。 
//該方法必須在啓動線程前調用。 值爲true時表示正常
 
td.setDaemon(true);
td2.setDaemon(true);

//啓動線程
td.start();
td2.start();

Thread.currentThread().setName("蕭炎");
for(int i=0;i<5;i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
}

}
}

 

package com.westos.Thread04;
 
public class ThreadsleepDome {
 
public static void main(String[] args) {

//創建對象
ThreadSleep ts=new ThreadSleep();
ThreadSleep ts2=new ThreadSleep();

ts.setName("張三");
ts2.setName("李四");

ts.start();
ts2.start();
}
}

 

stop()直接停止線程執行

interrupt():中斷線程。

 

package com.westos.Thread05;
 
public class ThreadStopInterrupt extends Thread{
 
public void run() {
System.out.println("程序開始了...");
//睡眠10秒
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// e.printStackTrace();
System.out.println("程序出現中斷異常...");
}
System.out.println("程序結束了...");
}
}

 

package com.westos.Thread05;
 
public class StopInterruptDome {
 
public static void main(String[] args) {
ThreadStopInterrupt tsi=new ThreadStopInterrupt();

tsi.start();
try {
tsi.sleep(3000);
//表示停止
// tsi.stop();
//中斷線程
tsi.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

 

前面我們學習了多線程的實現,除了上面繼承Thread類的這種方式呢,還有一種實現Runnable接口的方法,它也可以進行多線程的實現,但是其中的一些方法發生了改變,需要我們注意:

 

package com.westos.Runable;
 
 
/**
 * @author 傑哥
 *實現多線程的第二種方式:實現Runable接口
 */
public class RunnableDome implements Runnable{
 
public void run() {

for(int x=0;x<100;x++) {
//因爲這是第二種方式,不是之前的繼承Thread方式,所以不能直接調用getName方法
//Thread.currentThread()返回的是正在運行的線程
System.out.println(Thread.currentThread().getName()+":"+x);
}
}
}

 

package com.westos.Runable;
 
public class RunnableTest {
 
public static void main(String[] args) {

//創建RunableDome類對象
RunnableDome rd=new RunnableDome();

/**
 * Thread(Runnable target, String name) 分配新的 Thread 對象。
 * 這是Thread類有關Runnable接口的一種構造方法
 */
Thread t1=new Thread(rd,"楊過");
Thread t2=new Thread(rd,"小龍女");

t1.start();
t2.start();
}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章