java基礎10(多線程2)
線程的常用方法
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)