日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

多线程-Thread-Runnable

發(fā)布時(shí)間:2025/4/9 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程-Thread-Runnable 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.


一.多線程
???? 1.基本概念
???????? 進(jìn)程:正在運(yùn)行中的程序,一個(gè)進(jìn)程中至少包含一個(gè)線程
???????? 線程:進(jìn)程的任務(wù),執(zhí)行任務(wù)的一個(gè)通道,一個(gè)進(jìn)程中可以包含多個(gè)線程
???? 2.多線程執(zhí)行的特點(diǎn):
???????? 兩種方式:分時(shí)調(diào)度/搶占式調(diào)度(java屬于搶占)
二.Thread 類(java.lang)
???? 1.概述:使用該類表示多線程對(duì)象,只要?jiǎng)?chuàng)建一個(gè)Thread對(duì)象,就是一個(gè)線程對(duì)象產(chǎn)生了
???? 2.定義:public class Thread extends Object implements Runnable
???? 3.構(gòu)造方法:
???????? Thread():無參構(gòu)造,分配新的 Thread 對(duì)象
???????? Thread(String name):使用指定的名稱分配新的 Thread 對(duì)象,設(shè)置線程名稱
???????? Thread(Runnable target):接收Runnable接口子類對(duì)象,實(shí)例化Thread對(duì)象
???????? Thread(Runnable target, String name):接收Runnable接口子類對(duì)象,實(shí)例化Thread對(duì)象,并設(shè)置線程名稱
???? 4.靜態(tài)方法:
???????? public static Thread currentThread(){}:返回目前正在執(zhí)行的線程 [線程名,優(yōu)先級(jí),]
???????? public static void sleep(long millis) throws InterruptedException{}:使當(dāng)前線程休眠多少毫秒
???????? public static void yield(){}:將目前執(zhí)行的線程暫停,允許其它線程執(zhí)行
????
???? 5.常用方法:
???????? public void run(){}:如果該線程是使用獨(dú)立的 Runnable 運(yùn)行對(duì)象構(gòu)造的,則調(diào)用該 Runnable 對(duì)象的 run
???????????????????????????? 方法;否則,該方法不執(zhí)行任何操作并返回。<所以該方法應(yīng)自覺重寫!!!>
???????? public void start(){}:使該線程開始執(zhí)行;Java 虛擬機(jī)調(diào)用該線程的 run 方法
???????? public final String getName(){}:返回線程的名稱
???????? public final int getPriority(){}:返回線程優(yōu)先級(jí)
???????? public final void setName(String name){}:設(shè)定線程名稱
???????? public final void setPriority(int newPriority){}:設(shè)定線程的優(yōu)先值
???????? public final ThreadGroup getThreadGroup(){}:Returns the thread group to which this thread belongs.
???????????????????????????????????????????? This method returns null if this thread has died (been stopped).
???? 代碼演示:
???????

1 //多線程基本練習(xí)-Thread類 2 class MyThread extends Thread{ 3 //重寫run() 4 @Override 5 public void run(){ 6 for(int i = 0; i < 100; i++){ 7 System.out.println(Thread.currentThread()+"Jack"+i); 8 } 9 } 10 } 11 12 public class ThreadDemo{ 13 public static void main(String[] args){ 14 //創(chuàng)建一個(gè)線程 15 MyThread my = new MyThread(); 16 //啟動(dòng)線程 17 my.start(); 18 19 //主線程執(zhí)行如下任務(wù) 20 for(int i = 0; i<100; i++){ 21 System.out.println(Thread.currentThread()+"肉絲"+i); 22 } 23 24 //返回當(dāng)前運(yùn)行的線程名稱 25 String s = my.getName(); 26 System.out.println("當(dāng)前線程名稱為:"+s);//Thread-0 27 28 //修改線程名稱 29 my.setName("Smith--"); 30 System.out.println("修改后-當(dāng)前線程名稱為:"+my.getName()); 31 32 //返回線程優(yōu)先級(jí) 33 int i = my.getPriority(); 34 System.out.println("當(dāng)前線程優(yōu)先級(jí)為:"+i);//5 35 } 36 }
????????
三.Runnable 接口(java.lang)
???? 1.概述:Runnable 接口只有一個(gè)方法,run方法,因此實(shí)現(xiàn)Runnable接口的類,必須重寫run方法,否則,語法報(bào)錯(cuò);
???? 2.實(shí)現(xiàn)接口的好處:
???????? 由于類只能是單繼承(即只出現(xiàn)一次extends),若使用接口,則實(shí)現(xiàn)類可以繼承其他類,不占用繼承的位置;
???????? 可以多實(shí)現(xiàn),可以將編寫線程類和寫任務(wù)代碼(run()方法)的工作分離開;
???? 3.定義:
???????? @FunctionalInterface
???????? public interface Runnable
???? 4.方法:
???????? public void run() 使用實(shí)現(xiàn)接口 Runnable 的對(duì)象創(chuàng)建一個(gè)線程時(shí),啟動(dòng)該線程將導(dǎo)致在獨(dú)立執(zhí)行的線程中調(diào)用對(duì)象的 run 方法
代碼演示:
???? 1 //通過Runnable接口實(shí)現(xiàn)多線程 2 class MyRunnable implements Runnable{ 3 @Override 4 public void run(){ 5 for(int i = 0; i<100; i++){ 6 System.out.println("Smith----------"+i+Thread.currentThread()); 7 } 8 } 9 } 10 11 public class RunnableDemo{ 12 public static void main(String[] args){ 13 MyRunnable my = new MyRunnable(); 14 Thread myThread = new Thread(my,"smith"); 15 myThread.start(); 16 17 //返回當(dāng)前線程名稱 18 System.out.println("當(dāng)前線程:"+Thread.currentThread()); 19 20 for(int i = 0;i<100;i++){ 21 System.out.println("格林:==="+i+Thread.currentThread()); 22 } 23 } 24 }

死鎖現(xiàn)象:
????

1 class Zhangsan{ 2 public void say(){ 3 System.out.println("張三對(duì)李四說:你給你畫,我給你書"); 4 } 5 public void get(){ 6 System.out.println("張三得到畫了"); 7 } 8 } 9 10 class Lisi{ 11 public void say(){ 12 System.out.println("李四對(duì)張三說:你給我書,我就給你畫"); 13 } 14 public void get(){ 15 System.out.println("李四得到書了"); 16 } 17 } 18 //單例-餓漢式 19 public class ThreadDeadLock implements Runnable{ 20 private static Zhangsan zs = new Zhangsan(); 21 private static Lisi ls = new Lisi(); 22 private boolean flag = false; 23 @Override 24 public void run(){ 25 if(flag){ 26 synchronized(zs){ //單例模式,所以實(shí)例化對(duì)象只有一個(gè),可以作為鎖使用 27 zs.say(); 28 try{ 29 Thread.sleep(500); 30 }catch(InterruptedException e){ 31 e.printStackTrace(); 32 } 33 synchronized(ls){ 34 zs.get(); 35 } 36 } 37 }else{ 38 synchronized(ls){ 39 ls.say(); 40 try{ 41 Thread.sleep(500); 42 }catch(InterruptedException e){ 43 e.printStackTrace(); 44 } 45 synchronized(zs){ 46 ls.get(); 47 } 48 } 49 } 50 } 51 public static void main(String[] args){ 52 ThreadDeadLock t1 = new ThreadDeadLock(); 53 ThreadDeadLock t2 = new ThreadDeadLock(); 54 t1.flag = true; 55 t2.flag = false; 56 Thread thA = new Thread(t1); 57 Thread thB = new Thread(t2); 58 thA.start(); 59 thB.start(); 60 } 61 }

四.線程安全問題
???? 原因:當(dāng)多個(gè)線程使用共享的資源時(shí),容易發(fā)生數(shù)據(jù)安全的問題;
???? 解決方案:
???????? Java 提供了3種解決安全問題的方式;
???????????? 1:同步代碼塊
???????????? 2:同步方法
???????????? 3:Lock 接口
???? 1.同步代碼塊
???????

1 /*使用3個(gè)線程,模擬3個(gè)窗口,賣100張票; 2 要求每個(gè)線程賣出去的票,不能重復(fù)且不能是無效票; 3 使用一個(gè)變量表示100張票,每個(gè)窗口賣出去一張票,就將該變量的值減一,直到0為止; 4 使用同步代碼塊 5 */ 6 class MyRunnable implements Runnable{ 7 int ticket = 100;//總票數(shù),只能new一次該類,因?yàn)槊縿?chuàng)建一次對(duì)象就會(huì)有100張票 8 @Override 9 public void run(){ 10 String name = Thread.currentThread().getName();//獲取當(dāng)前線程名 11 while(true){ 12 synchronized(this){ 13 if(ticket<=0){ 14 break; 15 }else{ 16 System.out.println(name+"賣出第"+ticket+"號(hào)票"); 17 ticket--; 18 } 19 } 20 } 21 22 } 23 } 24 25 public class SellTicket{ 26 public static void main(String[] args){ 27 //創(chuàng)建任務(wù)對(duì)象 28 MyRunnable my = new MyRunnable(); 29 //創(chuàng)建線程 30 Thread t1 = new Thread(my,"窗口1"); 31 Thread t2 = new Thread(my,"窗口2"); 32 Thread t3 = new Thread(my,"窗口3"); 33 //開啟線程 34 t1.start(); 35 t2.start(); 36 t3.start(); 37 } 38 }

??? 2.同步方法
????????

1 class MyRunnable implements Runnable{ 2 //定義總票數(shù)為成員變量 3 int ticket = 100; 4 String name; 5 @Override 6 public void run(){ 7 name = Thread.currentThread().getName(); 8 //賣票任務(wù) 9 while(true){ 10 sell(); 11 if(ticket<=0){ 12 break; 13 } 14 } 15 } 16 //同步方法 17 public synchronized void sell(){ 18 if(ticket > 0){ 19 System.out.println(name+"賣出第"+ticket+"號(hào)票"); 20 ticket--; 21 } 22 } 23 } 24 25 public class SellTicket01{ 26 public static void main(String[] args){ 27 //創(chuàng)建任務(wù)對(duì)象 28 MyRunnable my = new MyRunnable(); 29 //創(chuàng)建多線程 30 Thread t1 = new Thread(my,"窗口1"); 31 Thread t2 = new Thread(my,"窗口2"); 32 Thread t3 = new Thread(my,"窗口3"); 33 //開啟多線程 34 t1.start(); 35 t2.start(); 36 t3.start(); 37 } 38 }

??? 3.Lock 接口
???????

1 import java.util.concurrent.locks.Lock; 2 import java.util.concurrent.locks.ReentrantLock; 3 class MyRunnable implements Runnable{ 4 //定義票數(shù)為成員變量 5 int ticket = 100; 6 //創(chuàng)建鎖對(duì)象 7 private static final Lock lock = new ReentrantLock(); 8 @Override 9 public void run(){ 10 String name = Thread.currentThread().getName(); 11 while(true){ 12 lock.lock(); 13 try{ 14 if(ticket > 0){ 15 System.out.println(name+"賣出了第"+ticket+"號(hào)票"); 16 ticket--; 17 }else{ 18 break; 19 } 20 }finally{ 21 lock.unlock(); 22 } 23 } 24 } 25 } 26 27 28 public class SellTicket02{ 29 public static void main(String[] args){ 30 //創(chuàng)建任務(wù)對(duì)象 31 MyRunnable my = new MyRunnable(); 32 //創(chuàng)建多線程 33 Thread t1 = new Thread(my,"窗口1"); 34 Thread t2 = new Thread(my,"窗口2"); 35 Thread t3 = new Thread(my,"窗口3"); 36 //開啟多線程 37 t1.start(); 38 t2.start(); 39 t3.start(); 40 41 } 42 }

五.使用匿名內(nèi)部類實(shí)現(xiàn)多線程
????

1 /*編寫程序,創(chuàng)建兩個(gè)線程對(duì)象,一根線程循環(huán)輸出“播放背景音樂”,另一根線程循環(huán)輸出 2 “顯示畫面”,要求線程實(shí)現(xiàn)Runnable接口,且使用匿名內(nèi)部類實(shí)現(xiàn)*/ 3 public class ThreadDemo003{ 4 public static void main(String[] args){ 5 new Thread(new Runnable(){ 6 @Override 7 public void run(){ 8 for(int i = 0; i < 100; i++){ 9 System.out.println("播放背景音樂"); 10 } 11 } 12 }).start(); 13 14 new Thread(new Runnable(){ 15 @Override 16 public void run(){ 17 for(int i = 0; i <100; i++){ 18 System.out.println("顯示畫面"); 19 } 20 } 21 }).start(); 22 } 23 } 1 /*編寫程序,創(chuàng)建兩個(gè)線程對(duì)象,一根線程循環(huán)輸出“播放背景音樂”,另一根線程循環(huán)輸出 2 “顯示畫面”,要求使用Thread類,且使用匿名內(nèi)部類實(shí)現(xiàn)*/ 3 public class ThreadDemo03{ 4 public static void main(String[] args){ 5 new Thread(){ 6 @Override 7 public void run(){ 8 for(int i = 0; i<100; i++){ 9 System.out.println("播放背景音樂"); 10 } 11 } 12 }.start(); 13 14 new Thread(){ 15 @Override 16 public void run(){ 17 for(int i = 0; i<100; i++){ 18 System.out.println("顯示畫面"); 19 } 20 } 21 }.start(); 22 } 23 } 24

六.ThreadGroup 類(java.lang)
???? 簡(jiǎn)介:線程組:java允許對(duì)一批線程進(jìn)行管理,使用ThreadGroup表示線程組,所有線程均有指定線程組,如果沒有顯式指定,則為默認(rèn)線程組.默認(rèn)情況下,子線程和創(chuàng)建他的父線程
???????? 屬于同一線程組.一旦某線程加入指定線程組內(nèi),該線程會(huì)一直屬于該組,直至死亡,運(yùn)行過程中不可改變.
???? 繼承關(guān)系:java.lang.Object--java.lang.ThreadGroup
???? 定義:public class ThreadGroup extends Object implements Thread.UncaughtExceptionHandler
???? 構(gòu)造器:
???????? ThreadGroup(String name): Constructs a new thread group.
???????? ThreadGroup(ThreadGroup parent, String name): Creates a new thread group.
???? 常用方法:
???????? public int activeCount(){}:Returns an estimate of the number of active threads in this thread group and its subgroups
???????? public int activeGroupCount(){}:Returns an estimate of the number of active groups in this thread group and its subgroups.
???????????????????????????????????????? Recursively iterates over all subgroups in this thread group.
???????? public int enumerate(Thread[] list) Throws SecurityException{}:
???????? public int enumerate(Thread[] list,boolean recurse)Throws SecurityException{}:Copies into the specified array every active thread
???????????????????????????????????????????????? in this thread group. If recurse is true, this method recursively enumerates all subgroups of
???????????????????????????????????????????????? this thread group and references to every active thread in these subgroups are also included.
???????????????????????????????????????????????? If the array is too short to hold all the threads, the extra threads are silently ignored.
???????? public final String getName(){}:Returns the name of this thread group.
???????? public final ThreadGroup getParent()Throws SecurityException{}:Returns the parent of this thread group.
???????? public final boolean isDaemon(){}:Tests if this thread group is a daemon thread group
???????? public final void checkAccess() Throws SecurityException{}:Determines if the currently running thread has permission to modify this thread group.
???????? public final void setDaemon(boolean daemon)Throws SecurityException{}:Changes the daemon status of this thread group.???
????
???? 代碼演示:獲取當(dāng)前系統(tǒng)內(nèi)運(yùn)行的所有線程組及線程名
???????

1 import java.util.List; 2 import java.util.ArrayList; 3 public class ThreadListDemo{ 4 public static void main(String[] args){ 5 for(String s : getThreadGroups(getRootThreadGroups())){ 6 System.out.println(s); 7 } 8 } 9 10 //getRootThreadGroups() 11 public static ThreadGroup getRootThreadGroups(){ 12 //get current threadgroup 13 ThreadGroup rootGroup = Thread.currentThread().getThreadGroup(); 14 while(true){ 15 if(rootGroup.getParent() != null){ 16 rootGroup = rootGroup.getParent(); 17 }else{ 18 break; 19 } 20 21 } 22 return rootGroup; 23 } 24 25 //getThreadGroups()傳入一個(gè)線程組,獲取該組內(nèi)所有子線程組 26 public static List<String> getThreadGroups(ThreadGroup group){ 27 List<String> threadList = getThreads(group);//存子線程組名,調(diào)用getThreads方法,返回線程組內(nèi)所有線程名 28 ThreadGroup[] groups = new ThreadGroup[group.activeGroupCount()];//活動(dòng)的線程組名 29 int count = group.enumerate(groups,false);//復(fù)制子線程組到線程組數(shù)據(jù),不遞歸復(fù)制 30 for(int i = 0; i< count; i++){ 31 threadList.addAll(getThreads(groups[i])); 32 } 33 return threadList; 34 } 35 36 37 //傳入一個(gè)線程組,返回該組內(nèi)所有線程名 38 public static List<String> getThreads(ThreadGroup group){ 39 List<String> threadList = new ArrayList<>();//存線程名 40 Thread[] list = new Thread[group.activeCount()];//活動(dòng)線程 41 int count = group.enumerate(list,false);//復(fù)制當(dāng)前進(jìn)程到list中 42 for(int i = 0; i< count; i++){ 43 threadList.add("名為:"+group.getName()+"的線程組,線程名為:"+list[i].getName()); 44 } 45 return threadList; 46 } 47 48 }

七.Executor 接口(java.io.concurrent)
簡(jiǎn)介:線程池:由于線程涉及到與操作系統(tǒng)交互,所以啟動(dòng)一個(gè)新線程的成本比較高,因此,java提供了線程池機(jī)制來提高性能,尤其是當(dāng)程序中需要大量生存期很短暫的線程時(shí),應(yīng)該考慮
???? 使用線程池.所謂線程池是指在系統(tǒng)啟動(dòng)時(shí)即創(chuàng)建大量空閑的線程,程序?qū)⒁粋€(gè)Runnable對(duì)象或Callable對(duì)象傳給線程池,線程池就會(huì)啟動(dòng)一個(gè)線程來執(zhí)行他們的run或call方法,當(dāng)方法
???? 結(jié)束時(shí),線程并不會(huì)死亡,而是返回線程池成為空閑狀態(tài),等待執(zhí)行下一個(gè)任務(wù)
定義: public interface Executor
方法:public void execute(Runnable command) Throws RejectedExecutionException | NullPointerException {}:Executes the given command at some time in the future
實(shí)現(xiàn)類:AbstractExecutorService, ForkJoinPool, ScheduledThreadPoolExecutor, ThreadPoolExecutor
子接口:ExecutorService, ScheduledExecutorService

轉(zhuǎn)載于:https://www.cnblogs.com/huguangqin/p/7128802.html

總結(jié)

以上是生活随笔為你收集整理的多线程-Thread-Runnable的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。