1. 程式人生 > >java基礎10(多線程2)

java基礎10(多線程2)

java、多線程

  1. 線程的常用方法

public final void join() 線程加入

作用:等待該線程中止,其他線程才能繼續搶著執行

public static void yield(): 線程禮讓

作用:暫停當前正在執行的線程對象,並執行其他線程。讓線程間的執行更和諧一些,但是實際上做不到。

public final void stop():線程死亡:直接殺死

public void interrupt():線程死亡:直接殺死,在死前,還可以有遺言(會執行後面的代碼,然後死去)。

static void sleep(long millis) 線程休眠:線程睡一會,會自己醒來

2.線程的生命周期

a.新建:創建一個線程對象

b.就緒:start()之後,有cpu的執行權,但沒有搶到執行資格

c.運行:有cpu的執行權,也有cpu的執行資格

d.有可能阻塞:休眠或者等待

e.死亡:run()方法執行完畢,調用stop()或者interrup()方法

生命周期圖如下:

技術分享

3.線程間通信

定義:不同線程間針對同一個資源進行操作


Student -- 被設置的資源對應的類

setThread -- 設置線程

getThread -- 獲取線程

StudnetDemo -- 測試類


public class Student {

private String name;

private int age;

//作為對象的一個標記,如果是false說明該對象沒有數據

private boolean flag;

//提供公共的方法設置信息

public synchronized void setInfo(String name,int age){

if (this.flag) {

//等待

try {

this.wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

//沒有值的話,在這裏給對對象設置數據

this.name = name;

this.age = age;

//更改標記,喚醒獲取線程獲取數據

this.flag = true;

this.notify();

}

//提供公共的方法獲取信息

public synchronized void getInfo(){

if (!this.flag) {

//沒有值

try {

this.wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

//有數據,取數據

System.out.println(this.name+"--"+this.age);

//取完數據之後,就沒有數據了

this.flag = false;

this.notify();

}

}


public class GetThread implements Runnable{

private Student s;

public GetThread(Student s){

this.s = s;

}

@Override

public void run() {

//獲取線程,獲取學生對象的姓名和年齡

while (true) {

s.getInfo();

}

}

}

}



public class SetThread implements Runnable{

private Student s;

private int x=0;

public SetThread(Student s){

this.s = s;

}

@Override

public void run() {

//給學生對象設置姓名和年齡

while (true) {

if (x%2==0) {

s.name = "周傑倫";

s.age = 40;

}else {

s.name = "林宥嘉";

s.age = 30;

}

x++;

}

}

}

public class StudentDemo {

public static void main(String[] args) {

//創建學生對象

Student s = new Student();

//創建設置線程和獲取線程

SetThread st = new SetThread(s);

GetThread gt = new GetThread(s);

Thread t1 = new Thread(st);

Thread t2 = new Thread(gt);

//開啟線程

t1.start();

t2.start();

}


}

4.線程組

定義:Java中使用ThreadGroup來表示線程組,它可以對一批線程進行分類管理,Java允許程序直接對線程組進行控制。默認情況下,所有的線程都屬於主線程組。

主要方法:

public final ThreadGroup getThreadGroup():獲取線程對應的線程組對象

Thread(ThreadGroup group, Runnable target):線程設置分組


案例1:創建線程獲取對應的線程組對象,並獲取名稱

//創建兩個線程

MyThread mt1 = new MyThread();

MyThread mt2 = new MyThread();

//獲取上面兩個線程對應的線程組對象

ThreadGroup tg1 = mt1.getThreadGroup();

ThreadGroup tg2 = mt2.getThreadGroup();

//獲取線程組對象的名稱

System.out.println(tg1.getName());

System.out.println(tg2.getName());

案例2:創建線程組對象,給線程分配線程組


ThreadGroup tg = new ThreadGroup("big");

Thread t3 = new Thread(tg, new MyRunnable());

Thread t4 = new Thread(tg, new MyRunnable());

//獲取t3和t4的線程組對象

ThreadGroup tg3 = t3.getThreadGroup();

ThreadGroup tg4 = t4.getThreadGroup();

System.out.println(tg3.getName());

System.out.println(tg4.getName());


5.線程池

引入原因:程序啟動一個新線程成本是比較高的,因為它涉及到要與操作系統進行交互。而使用線程池可以很好的提高性能,尤其是當程序中要創建大量生存期很短的線程時,更應該考慮使用線程池。

特點:線程池裏的每一個線程代碼結束後,並不會死亡,而是再次回到線程池中成為空閑狀態,等待下一個對象來使用。

線程池的創建方法:

public static ExecutorService newFixedThreadPool(int nThreads)

線程池的使用步驟:

a.創建線程池對象

ExecutorService pool = Executors.newFixedThreadPool(2);


b.創建Runnable實例

MyRunnable my = new MyRunnable();


c.提交Runnable實例

pool.submit(my);

pool.submit(my);


d.關閉線程池

pool.shutdown();


6.定時器(Timer):

主要方法:

public Timer()構造

public void schedule(TimerTask task, long delay)延遲多久執行任務

public void schedule(TimerTask task,long delay,long period)延遲多久執行任務,並以後每隔多久執行一次

public boolean cancel()取消這個任務


TimerTask

public abstract void run()放的是所要執行的任務代碼


案例:延遲5秒鐘,打印hellojava,以後每隔一秒打印一次

public static void main(String[] args) {

Timer t = new Timer();

t.schedule(new MyTimerTask2(), 5000, 1000);

/**

* 參數1:要執行的任務

* 參數2:延遲多久執行

* 參數3:執行一次之後,每隔多久重復執行

*/

}


}


class MyTimerTask2 extends TimerTask{

@Override

public void run() {

System.out.println("hellojava");

}

}


java基礎10(多線程2)