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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JAVA自学笔记23

發布時間:2023/12/20 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JAVA自学笔记23 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JAVA自學筆記23

1、多線程
1)引入:

2)進程
是正在運行的程序。是系統進行資源分配和調用的獨立單位。每一個進程都有它自己的內存空間和系統資源。
多進程:
單進程的計算機只能做一件事情,而現在的計算機都可以做多件事情。CPU在某個時間點上只能做一件事。每一個進程都有它自己的內存空間和系統資源。
3)多線程
-是進程中的單個順序控制流,是一條執行路徑
-一個進程如果只有一條執行路徑,則稱為單線程程序。一個進程如果有多條執行路徑,稱為多線程程序。
4)并行與并發
前者是邏輯上同時發生,指在某一個時間段內同時運行多個程序;后者是物理上同時發生,指在,某一個時間點內同時運行多個程序
5)Java程序運行原理
java命令會啟動java虛擬機,啟動jvm,等于啟動了一個應用程序,也就是啟動了一個進程,該進程會自動地啟動一個“主線程”,然后主線程去調用某個類的main方法,所以main方法運行在主線程中。在此之前的所有程序都是單線程的。

JVM的啟動時單線程還是多線程的呢?
多線程的。垃圾回收線程也要先啟動,否則很容易出現內容溢出。最少都啟動了兩個線程。


創建新執行線程有兩種方法,一種方法時將類聲明為Thread的子類。該子類應重寫Thread類的run方法。接下來可以分配并啟動該子類的實例。
即-自定義一個繼承自Thread的類
-重寫run()方法(不是類中的所有代碼都需要被線程執行。此時,為了區分哪些代碼能夠被執行。java提供了Thread類中的run()方法用于包含那些被執行的代碼。)
-創建對象
-啟動線程
另一種方法是聲明實現Runnable接口的類,該類然后實現run方法,然后就可以分配該類的實例。start()方法:使該線程開始執行,Java虛擬機調用該線程的run方法。它和run()的區別是run()僅僅是封裝被線程執行的代碼,直接調用的是普通方法start()首先啟動了線程,然后再由jvm去調用該線程的run()方法。

//多線程的實現 //方式1 public class MyThread extends Thread{ public void run(){ //一般來說,被線程執行的代碼肯定是比較耗時的 for(int x=0;x<10000;x++){ System.out.println("cc"+x); } } }//測試類 public class MyThreadDemo{ public static void main (String[] args){ //創建線程對象 MyThread my1=new MyThread(); MyThread my2=new MyThread(); //啟動線程 my1.start(); my2.start(); } }

5)獲取和設置線程對象的名稱
獲取:
public final String getName(); //程序將輸出Thread-?,?按順序從0開始

設置
public final void setName(String name);

public class MyThread extends Thread{ //無參構造 public MyThread(){} //帶參構造 public MyThread(String name){ super(name); } public void run(){ //一般來說,被線程執行的代碼肯定是比較耗時的 for(int x=0;x<10000;x++){ System.out.println("getName()+cc"+x); } } } //創建線程對象 MyThread my1=new MyThread(); MyThread my2=new MyThread(); //設置名稱 my1.setName("cc"); my2.setName("dd"); //啟動線程 my1.start();//Thread-0 my2.start();//Thread-1 } }//帶參構造 MyThread my1=new Mythread("許先生"); MyThread my1=new Mythread("劉先生");//獲取main方法對應線程的名稱 //public static Thread currentThread() 返回當前正在執行的線程對象 System.out.println(Thread currrentThread().getName());

6)線程調度
①分時調度模型:
所有線程輪流使用CPU的使用權,平均分配每個線程占用CPU的時間片
②搶占式調度模型 優先讓優先級高的線程使用CPU。如果線程的優先級相同,那么會隨機選擇一個,優先級高的線程獲取的CPU時間片相對多一些。Java使用此類模型

設置優先級的方法:
public final void setPriority (newPriority)
MAX_PRIORITY=10
MIN_PRIORITY=1
NORM_PRIORITY=5

獲取線程對象的優先級,默認優先級是5:
public final int getPriority()

public class ThreadPriority extends Thread{ public void run(){ //一般來說,被線程執行的代碼肯定是比較耗時的 for(int x=0;x<10000;x++){ System.out.println("getName()+cc"+x); } } }public class ThreadPriorityDemo{ public static void main(String args[]){ ThreadPriority tp1=new ThreadPriority(); ThreadPriority tp2=new ThreadPriority(); ThreadPriority tp3=new ThreadPriority(); tp1.setName("aa"); tp2.setName("bb"); tp3.setName("cc");tp1.getPriority(); tp2.getPriority(); tp3.getPriority()tp1.setPriorty(8);//存在隨機性tp1.start(); tp2.start(); tp3.start(); } }

7)線程控制
線程休眠
public static void sleep(long mills)
在指定毫秒內讓當前正在執行的線程休眠
線程加入
public final void join()
等待該線程終止

public class ThreadJoin extends Thread{ public void run(){ for(int x=0;x<10000;x++){ System.out.println("getName()+cc"+x); } } } public class ThreadJoinDemo{ public static void main(String args[]){ ThreadJoin tp1=new ThreadJoin(); ThreadJoin tp2=new ThreadJoin(); ThreadJoin tp3=new ThreadJoin(); tp1.setName("aa"); tp2.setName("bb"); tp3.setName("cc");tp1.start(); tp1.join(); tp2.start(); tp3.start(); } }

線程禮讓
public static void yield()

public class ThreadJoin extends Thread{ public void run(){ for(int x=0;x<10000;x++){ System.out.println("getName()+cc"+x); Thread.yield(); } } } public class ThreadYieldDemo{ public static void main(String args[]){ ThreadYield tp1=new ThreadYield(); ThreadYield tp2=new ThreadYield();tp1.setName("aa"); tp2.setName("bb");tp1.start(); tp2.start();} }

后臺線程
public final void setDaemon(boolean on)
將該線程標記為守護線程或用戶線程,當正在運行的線程都是守護線程時,jvm退出。必須在啟動線程前調用。

中斷線程
public final void stop()//已過時但仍可使用,具有不安全性
public void interrupt()//把線程狀態終止,并拋出InterruptedException 異常

public class ThreadStop extends Thread{ public void run(){ System.out.println("開始執行:"+new Date()); } } public class ThreadStopDemo{ public static void main(String args[]){ ThreadStop ts=new ThreadStop(); ts.start(); Thread.sleep(3000); //ts.stop(); ts.intereupt(); } }

8)線程生命周期圖解:

9)多線程的實現方案2
①好處:可以避免由于java單繼承而帶來的局限性。適合多個相同程序的代碼去處理同一個資源的情況,把線程同程序的代碼,數據有效分離,較好地體現; 面向對象的設計思想。
-自定義類MyRunnable實現Runnable接口
-重寫run()方法
-創建MyRunnable類的對象
-創建Thread類的對象,作為上一步驟的參數傳遞

public class MyRunnable implements Runnable{ public void run(){ for(int x=0;x<100){ System.out.println(Thread.currentThread.geiName()+":"+x); } } } public class MyRunnableDemo{ public static void main(String args[]){ MyRunnable my=new MyRunnable();//Thread t1=new Thread(my,"cc"); //Thread t2=new Thread(my,"dd"); Thread t1=new Thread(my); Thread t2=new Thread(my); t1.setName("cc"); t1.setName("dd"); t1.start(); t2.start(); } }

②兩種方式的比較圖解

@例題1:售賣電影票

public class SellTicketDemo{ public static void main(String args[]){ SellTicket st1=new SelTicket(); SellTicket st2=new SelTicket(); SellTicket st3=new SelTicket();st1.setName("窗口1"); st2.setName("窗口2"); st3.setName("窗口3");st1.start(); st2.start(); st3.start(); } }public class SellTicket extends Thread{ public void run(){ private static int tickets=100;public void run(){ while(true){ if(tickets>0){ System.out.println(getName()+"正在售出第"+(tickets--)+"張票"); } } } } } //第二種方式 public class SellTickets implements Runnable{ private int tickets=100; public void run(){ while(true){ if(tickets>0){ System.out.println(getName()+"正在售出第"+(tickets--)+"張票"); } } } } public class void main(String args[]){ SellTicket st=new SellTicket();Thread t1=new Thread(st,"窗口1"); Thread t2=new Thread(st,"窗口2"); Thread t1=new Thread(st,"窗口3");t1.start(); t2.start(); t3.start(); }

改進每次售出一張票延遲0.1秒

//第二種方式 public class SellTickets implements Runnable{ private int tickets=100; //創建鎖對象 private Object obj =new Object(); public void run(){ synchronized(obj){ while(true){ if(tickets>0){ Thread.sleep(1000); System.out.println(getName()+"正在售出第"+(tickets--)+"張票"); }} } } } public class void main(String args[]){ SellTicket st=new SellTicket();Thread t1=new Thread(st,"窗口1"); Thread t2=new Thread(st,"窗口2"); Thread t1=new Thread(st,"窗口3");t1.start(); t2.start(); t3.start(); }

出現了問題:
①相同號碼的票售出多次
②出現了負數序號的票
CPU的每一次執行必須是一個原子性(最簡單基本的)操作。是由于隨機性和延遲導致的

利用同步塊的方式解決上述問題
同步代碼塊:
格式:synchronized(對象)(需要同步的代碼;)
可以解決安全問題,其對象可以是任何對象。
把多條語句操作共享數據的部分給包起來
同步的好處與弊端:
好處:同步的出現解決了多線程的安全問題
弊端:當線程相當多時,因為每個線程都會去判斷同步上的鎖,非常耗費系統資源
前提:多個線程使用同一把鎖
同步方法:把同步關鍵字加載到方法上
A:同步代碼塊的鎖對象是誰呢?
* 任意對象。
*
* B:同步方法的格式及鎖對象問題?
* 把同步關鍵字加在方法上。
*
* 同步方法是誰呢?
* this
*
* C:靜態方法及鎖對象問題?
* 靜態方法的鎖對象是誰呢?
* 類的字節碼文件對象。(反射會講)

//再次改進 public class SellTicketDemo {public static void main(String[] args) {// 創建資源對象SellTicket st = new SellTicket();// 創建三個線程對象Thread t1 = new Thread(st, "窗口1");Thread t2 = new Thread(st, "窗口2");Thread t3 = new Thread(st, "窗口3");// 啟動線程t1.start();t2.start();t3.start();} } package cn.itcast_11;public class SellTicket implements Runnable {// 定義100張票private static int tickets = 100;// 定義同一把鎖private Object obj = new Object();private Demo d = new Demo();private int x = 0;@Overridepublic void run() {while (true) {if(x%2==0){synchronized (SellTicket.class) {if (tickets > 0) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+ "正在出售第" + (tickets--) + "張票 ");}}}else {private static synchronized void sellTicket() {if (tickets > 0) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+ "正在出售第" + (tickets--) + "張票 ");} } }

8)線程安全的類
StringBuffered
Vector
Hashtable
collections下有很多線程安全的類

轉載于:https://www.cnblogs.com/Tanqurey/p/10485332.html

總結

以上是生活随笔為你收集整理的JAVA自学笔记23的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。