多線程方式實現(1) 方式1:繼承Thread類。 * 步驟 * A:自定義類MyThread繼承Thread類。 * B:MyThread類裡面重寫run()? * 為什麼是run()方法呢? * C:創建對象 * D:啟動線程 */ package cn.itcast_02; /* * 該類要重 ...
多線程方式實現(1)
方式1:繼承Thread類。
* 步驟
* A:自定義類MyThread繼承Thread類。
* B:MyThread類裡面重寫run()?
* 為什麼是run()方法呢?
* C:創建對象
* D:啟動線程
*/
package cn.itcast_02; /* * 該類要重寫run()方法,為什麼呢? * 不是類中的所有代碼都需要被線程執行的。 * 而這個時候,為了區分哪些代碼能夠被線程執行,java提供了Thread類中的run()用來包含那些被線程執行的代碼。 */ public class MyThread extends Thread { @Override public void run() { // 自己寫代碼 // System.out.println("好好學習,天天向上"); // 一般來說,被線程執行的代碼肯定是比較耗時的。所以我們用迴圈改進 for (int x = 0; x < 200; x++) { System.out.println(x); } } }
package cn.itcast_02; /* * 需求:我們要實現多線程的程式。 * 如何實現呢? * 由於線程是依賴進程而存在的,所以我們應該先創建一個進程出來。 * 而進程是由系統創建的,所以我們應該去調用系統功能創建一個進程。 * Java是不能直接調用系統功能的,所以,我們沒有辦法直接實現多線程程式。 * 但是呢?Java可以去調用C/C++寫好的程式來實現多線程程式。 * 由C/C++去調用系統功能創建進程,然後由Java去調用這樣的東西, * 然後提供一些類供我們使用。我們就可以實現多線程程式了。 * 那麼Java提供的類是什麼呢? * Thread * 通過查看API,我們知道了有2中方式實現多線程程式。 * * 方式1:繼承Thread類。 * 步驟 * A:自定義類MyThread繼承Thread類。 * B:MyThread類裡面重寫run()? * 為什麼是run()方法呢? * C:創建對象 * D:啟動線程 */ public class MyThreadDemo { public static void main(String[] args) { // 創建線程對象 // MyThread my = new MyThread(); // // 啟動線程 // my.run(); // my.run(); // 調用run()方法為什麼是單線程的呢? // 因為run()方法直接調用其實就相當於普通的方法調用,所以你看到的是單線程的效果 // 要想看到多線程的效果,就必須說說另一個方法:start() // 面試題:run()和start()的區別? // run():僅僅是封裝被線程執行的代碼,直接調用是普通方法 // start():首先啟動了線程,然後再由jvm去調用該線程的run()方法。 // MyThread my = new MyThread(); // my.start(); // // IllegalThreadStateException:非法的線程狀態異常 // // 為什麼呢?因為這個相當於是my線程被調用了兩次。而不是兩個線程啟動。 // my.start(); // 創建兩個線程對象 MyThread my1 = new MyThread(); MyThread my2 = new MyThread(); my1.start(); my2.start(); } }
獲取和設置線程對象名稱
//我要獲取main方法所在的線程對象的名稱,該怎麼辦呢?
//遇到這種情況,Thread類提供了一個很好玩的方法:
//public static Thread currentThread():返回當前正在執行的線程對象
System.out.println(Thread.currentThread().getName());
package cn.itcast_03; public class MyThread extends Thread { public MyThread() { } public MyThread(String name){ super(name); } @Override public void run() { for (int x = 0; x < 100; x++) { System.out.println(getName() + ":" + x); } } }
package cn.itcast_03; /* * 如何獲取線程對象的名稱呢? * public final String getName():獲取線程的名稱。 * 如何設置線程對象的名稱呢? * public final void setName(String name):設置線程的名稱 * * 針對不是Thread類的子類中如何獲取線程對象名稱呢? * public static Thread currentThread():返回當前正在執行的線程對象 * Thread.currentThread().getName() */ public class MyThreadDemo { public static void main(String[] args) { // 創建線程對象 //無參構造+setXxx() // MyThread my1 = new MyThread(); // MyThread my2 = new MyThread(); // //調用方法設置名稱 // my1.setName("林青霞"); // my2.setName("劉意"); // my1.start(); // my2.start(); //帶參構造方法給線程起名字 // MyThread my1 = new MyThread("林青霞"); // MyThread my2 = new MyThread("劉意"); // my1.start(); // my2.start(); //我要獲取main方法所在的線程對象的名稱,該怎麼辦呢? //遇到這種情況,Thread類提供了一個很好玩的方法: //public static Thread currentThread():返回當前正在執行的線程對象 System.out.println(Thread.currentThread().getName()); } } /* 名稱為什麼是:Thread-? 編號 class Thread { private char name[]; public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0); } private void init(ThreadGroup g, Runnable target, String name, long stackSize) { init(g, target, name, stackSize, null); } private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc) { //大部分代碼被省略了 this.name = name.toCharArray(); } public final void setName(String name) { this.name = name.toCharArray(); } private static int threadInitNumber; //0,1,2 private static synchronized int nextThreadNum() { return threadInitNumber++; //return 0,1 } public final String getName() { return String.valueOf(name); } } class MyThread extends Thread { public MyThread() { super(); } } */
線程調度及獲取和設置線程優先順序
package cn.itcast_04; public class ThreadPriority extends Thread { @Override public void run() { for (int x = 0; x < 100; x++) { System.out.println(getName() + ":" + x); } } }
package cn.itcast_04; /* * 我們的線程沒有設置優先順序,肯定有預設優先順序。 * 那麼,預設優先順序是多少呢? * 如何獲取線程對象的優先順序? * public final int getPriority():返回線程對象的優先順序 * 如何設置線程對象的優先順序呢? * public final void setPriority(int newPriority):更改線程的優先順序。 * * 註意: * 線程預設優先順序是5。 * 線程優先順序的範圍是:1-10。 * 線程優先順序高僅僅表示線程獲取的 CPU時間片的幾率高,但是要在次數比較多,或者多次運行的時候才能看到比較好的效果。 * * IllegalArgumentException:非法參數異常。 * 拋出的異常表明向方法傳遞了一個不合法或不正確的參數。 * */ public class ThreadPriorityDemo { public static void main(String[] args) { ThreadPriority tp1 = new ThreadPriority(); ThreadPriority tp2 = new ThreadPriority(); ThreadPriority tp3 = new ThreadPriority(); tp1.setName("東方不敗"); tp2.setName("岳不群"); tp3.setName("林平之"); // 獲取預設優先順序 // System.out.println(tp1.getPriority()); // System.out.println(tp2.getPriority()); // System.out.println(tp3.getPriority()); // 設置線程優先順序 // tp1.setPriority(100000); //設置正確的線程優先順序 tp1.setPriority(10); tp2.setPriority(1); tp1.start(); tp2.start(); tp3.start(); } }
練習版
package Day23; /* * * 方式1:繼承Thread類。 * 步驟 * A:自定義類MyThread繼承Thread類。 * B:MyThread類裡面重寫run()? * 為什麼是run()方法呢? * C:創建對象 * D:啟動線程 */ public class ThreadDemo { public static void main(String[] args) { //創建對象 MyThreadDemo myd = new MyThreadDemo(); MyThreadDemo myd1 = new MyThreadDemo(); MyThreadDemo myd2 = new MyThreadDemo(); //啟動線程 //public void start()使該線程開始執行;Java 虛擬機調用該線程的 run 方法 //結果是兩個線程併發地運行;當前線程(從調用返回給 start 方法)和另一個線程(執行其 run 方法)。 //設置該線程對象的名稱 myd.setName("劉備"); myd1.setName("關羽"); myd2.setName("張飛"); //設置線程執行優先順序 //public final void setPriority(int newPriority)更改線程的優先順序。 //參數:newPriority - 要為線程設定的優先順序 myd.setPriority(1); myd1.setPriority(10); myd2.setPriority(5); // //創建對象的同時設置線程名稱---- // MyThreadDemo myd2 = new MyThreadDemo("長江"); // MyThreadDemo myd3 = new MyThreadDemo("黃河"); //運行調用-----輸出查看 myd.start(); myd1.start(); myd2.start(); } }
線程式控制制之線程休眠
package cn.itcast_04; import java.util.Date; public class ThreadSleep extends Thread { @Override public void run() { for (int x = 0; x < 100; x++) { System.out.println(getName() + ":" + x + ",日期:" + new Date()); // 睡眠 // 困了,我稍微休息1秒鐘 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
package cn.itcast_04; /* * 線程休眠 * public static void sleep(long millis) */ public class ThreadSleepDemo { public static void main(String[] args) { ThreadSleep ts1 = new ThreadSleep(); ThreadSleep ts2 = new ThreadSleep(); ThreadSleep ts3 = new ThreadSleep(); ts1.setName("林青霞"); ts2.setName("林志玲"); ts3.setName("林志穎"); ts1.start(); ts2.start(); ts3.start(); } }
線程式控制制之線程之加入線程
package Day23; //創建新執行線程有兩種方法。一種方法是將類聲明為 Thread 的子類。 // 該子類應重寫 Thread 類的 run 方法。 public class ThreadDemo1 extends Thread { //重寫Thread中的run方法 @Override public void run() { for(int x=0;x<100;x++){ //獲取線程對象的名稱 System.out.println(getName()+":"+x); } } }
package Day23; import com.sun.org.apache.bcel.internal.generic.NEW; //線程式控制制之加入線程 //public final void join() // throws InterruptedException等待該線程終止。----該線程終止後再運行其他的 public class join { public static void main(String[] args) throws InterruptedException { //創建ThreadDemo1對象 ThreadDemo1 TD = new ThreadDemo1(); ThreadDemo1 TD1 = new ThreadDemo1(); ThreadDemo1 TD2 = new ThreadDemo1(); //設置線程對象名稱 //public final void setName(String name)改變線程名稱,使之與參數 name 相同。 TD.setName("劉備"); TD1.setName("關羽"); TD2.setName("張飛"); //執行線程 TD.start(); //首先執行此線程---此線程執行完畢後再執行其他線程 //public final void join() //throws InterruptedException等待該線程終止 TD.join(); TD1.start(); TD2.start(); } }
線程式控制制之線程禮讓
public static void yield()
- 暫停當前正在執行的線程對象,並執行其他線程。
package cn.itcast_04; public class ThreadYield extends Thread { @Override public void run() { for (int x = 0; x < 100; x++) { System.out.println(getName() + ":" + x); Thread.yield(); } } }
package cn.itcast_04; /* * public static void yield():暫停當前正在執行的線程對象,並執行其他線程。 * 讓多個線程的執行更和諧,但是不能靠它保證一人一次。 */ public class ThreadYieldDemo { public static void main(String[] args) { ThreadYield ty1 = new ThreadYield(); ThreadYield ty2 = new ThreadYield(); ty1.setName("林青霞"); ty2.setName("劉意"); ty1.start(); ty2.start(); } }
線程式控制制之守護線程
package cn.itcast_04; public class ThreadDaemon extends Thread { @Override public void run() { for (int x = 0; x < 100; x++) { System.out.println(getName() + ":" + x); } } }
package cn.itcast_04; /* * public final void setDaemon(boolean on):將該線程標記為守護線程或用戶線程。 * 當正在運行的線程都是守護線程時,Java 虛擬機退出。 該方法必須在啟動線程前調用。 * * 游戲:坦克大戰。 */ public class ThreadDaemonDemo { public static void main(String[] args) { ThreadDaemon td1 = new ThreadDaemon(); ThreadDaemon td2 = new ThreadDaemon(); td1.setName("關羽"); td2.setName("張飛"); // 設置守護線程 td1.setDaemon(true); td2.setDaemon(true); td1.start(); td2.start(); //主線程---主線程結束--守護線程也會隨之停止 Thread.currentThread().setName("劉備"); for (int x = 0; x < 5; x++) { System.out.println(Thread.currentThread().getName() + ":" + x); } } }
線程式控制制之中斷線程
public void interrupt():中斷線程。 把線程的狀態終止,並拋出一個InterruptedException
package cn.itcast_04; import java.util.Date; public class ThreadStop extends Thread { @Override public void run() { System.out.println("開始執行:" + new Date()); // 我要休息10秒鐘,親,不要打擾我哦 try { Thread.sleep(10000); } catch (InterruptedException e) { // e.printStackTrace(); System.out.println("線程被終止了"); } System.out.println("結束執行:" + new Date()); } }
package cn.itcast_04; /* * public final void stop():讓線程停止,過時了,但是還可以使用。 * public void interrupt():中斷線程。 把線程的狀態終止,並拋出一個InterruptedException。 */ public class ThreadStopDemo { public static void main(String[] args) { ThreadStop ts = new ThreadStop(); ts.start(); // 你超過三秒不醒過來,我就乾死你 try { Thread.sleep(3000); // ts.stop(); ts.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } } }