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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java学习笔记(13)

發(fā)布時間:2025/3/20 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java学习笔记(13) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

StringBuffer?

增加

    append(boolean b)? ? 可以添加任意類型的數據到容器中

    insert(int offset,boolean b)? 指定插入的索引值,插入對應的內容? ? (offset可以理解為想插入的東西在插入后的索引值為多少,也就是想插入地方右區(qū)間的索引值)

刪除

    delete(int start ,int end)? ? 根據指定的開始與結束的索引值刪除對應的內容

    deleteCharAt(int index)? ?根據指定的索引值刪除一個字符

修改

    replace(int start,int end,String str)? 根據指定的開始與結束索引值替代成指定的內容

    reverse()? ? ? 翻轉字符串緩沖類的內容。? ?abc————>cba

    setCharAt(int index,char ch)? 把指定索引值的字符替換指定的字符。

    subString(int start,int end)? ?根據指定的索引值截取子串

    ensureCapacity(int minimumCapacity)? ?指定StringBuffer內部的字符數組長度的。

查看

    indexOf(String str,int fromIndex)? ?查找指定字符串第一次出現的索引值,并且指定開始查找的位置

    capacity()? ?查看當前字符數組的長度

    charAt(int index)? ?根據指定的索引值查找字符

    lastIndexOf(String str)? 查找指定字符最后一次出現的索引值

    length() 存儲的字符個數

    toString()? ?把字符串緩沖類的內容轉換成字符串返回

判斷

?

public static void main(String[] args) {// TODO Auto-generated method stub//先使用StringBuffer無參的構造函數創(chuàng)建一個字符串緩沖類。StringBuffer sb=new StringBuffer();sb.append("abc");System.out.println("字符串緩沖類的內容:"+sb);/* 添加sb.append(true);sb.append(3.14f);System.out.println("字符串緩沖類的內容:"+sb);*///插入sb.insert(2, "小明");System.out.println("字符串緩沖類的內容:"+sb);//刪除sb.delete(2, 4); //刪除的時候也是包頭不包尾的System.out.println("字符串緩沖類的內容:"+sb);sb.insert(2, "小明");sb.deleteCharAt(3);System.out.println("字符串緩沖類的內容:"+sb);}結果: 字符串緩沖類的內容:abc 字符串緩沖類的內容:ab小明c 字符串緩沖類的內容:abc 字符串緩沖類的內容:ab小c public static void main(String[] args) {// TODO Auto-generated method stub//先使用StringBuffer無參的構造函數創(chuàng)建一個字符串緩沖類。StringBuffer sb=new StringBuffer();sb.append("abc");System.out.println("字符串緩沖類的內容:"+sb);/* 添加sb.append(true);sb.append(3.14f);System.out.println("字符串緩沖類的內容:"+sb);*///插入sb.insert(2, "小明");System.out.println("字符串緩沖類的內容:"+sb);//刪除/*sb.delete(2, 4); //刪除的時候也是包頭不包尾的System.out.println("字符串緩沖類的內容:"+sb);sb.insert(2, "小明");sb.deleteCharAt(3);System.out.println("字符串緩沖類的內容:"+sb);*///修改sb.replace(2, 4, "陳小狗");System.out.println("字符串緩沖類的內容:"+sb);sb.reverse();System.out.println("字符串緩沖類的內容:"+sb);sb.reverse();sb.setCharAt(3, '紅');System.out.println("字符串緩沖類的內容:"+sb);System.out.println("字符串的內容:"+sb.substring(2, 4));sb.ensureCapacity(20);}結果: 字符串緩沖類的內容:abc 字符串緩沖類的內容:ab小明c 字符串緩沖類的內容:ab陳小狗c 字符串緩沖類的內容:c狗小陳ba 字符串緩沖類的內容:ab陳紅狗c 字符串的內容:陳紅 public static void main(String[] args) {// TODO Auto-generated method stubStringBuffer sb=new StringBuffer();sb.append("abcjavaabc");//查找System.out.println("索引值為:"+sb.indexOf("abc", 0));System.out.println("索引值為:"+sb.indexOf("abc", 3));//sb.ensureCapacity(20);sb.append("javajava");System.out.println("查看字符數組的長度:"+sb.capacity());System.out.println("存儲字符的個數:"+sb.length());System.out.println("根據指定的索引值查找字符:"+sb.charAt(2));System.out.println("轉換成字符串輸出:"+sb.toString());}結果: 索引值為:0 索引值為:7 查看字符數組的長度:34 存儲字符的個數:18 根據指定的索引值查找字符:c 轉換成字符串輸出:abcjavaabcjavajava

StringBuffer與StringBuilder的相同處與不同處:

    相同點:

      1.兩個類都是字符串緩沖類

      2.兩個類的方法與實現都是一致的

    不同點:

      1.StringBuffer是線程安全的,操作效率低,StringBuilder是線程非安全的,操作效率高

      2.StringBuffer是jdk1.0出現的,StringBuilder是jdk1.5的時候出現的

推薦使用:StringBuilder,因為操作效率高。

?

System類? ?系統(tǒng)類    主要用于獲取系統(tǒng)的屬性數據

System類常用的方法:

    arraycopy(Object src, int srcPos, Object dest, int destPos, int length)?

import java.util.*; public class Demo1 { /*arraycopy(Object src, int srcPos, Object dest, int destPos, int length) src - 源數組。srcPos - 源數組中的起始位置。dest - 目標數組。destPos - 目標數據中的起始位置。length - 要復制的數組元素的數量。* */public static void main(String[] args) {// TODO Auto-generated method stubint[] srcArr= {10,12,14,16,19};//把srcArr數組的元素拷貝到destArr數組中int[] destArr=new int[4];System.arraycopy(srcArr, 1, destArr, 0, 4);System.out.println("目標數組的元素:"+Arrays.toString(destArr));}}結果: 目標數組的元素:[12, 14, 16, 19]

    currentTimeMillis()    獲取當前系統(tǒng)時間? ? ? ?重點

System.out.println("當前的系統(tǒng)時間是:"+System.currentTimeMillis());結果: 當前的系統(tǒng)時間是:1549623586306

    exit(int status)      退出jvm    如果參數是0表示正常退出jvm,非0表示異常退出jvm  0或者非0的數據都可以退出jvm,對于用戶而言沒有任何區(qū)別    一般

public static void main(String[] args) {// TODO Auto-generated method stubint[] srcArr= {10,12,14,16,19};//把srcArr數組的元素拷貝到destArr數組中int[] destArr=new int[4];System.arraycopy(srcArr, 1, destArr, 0, 4);System.exit(0); //jvm退出... 0或者非0的數據都可以退出jvm。對于用戶而言沒有任何區(qū)別System.out.println("目標數組的元素:"+Arrays.toString(destArr));System.out.println("當前的系統(tǒng)時間是:"+System.currentTimeMillis());}結果:

(編程習慣:try塊中一般傳0,catch中一般傳非0,其實傳什么也可以達到效果)?

    gc()       建議jvm趕快啟動垃圾回收器回收垃圾

finalize() 如果一個對象被回收器回收的時候,會先調用對象的finalize()方法? ? 我們如果想要看到System.gc()的結果,可以重寫finalize方法

import java.util.*; public class Demo1 { /* gc() 建議jvm趕快啟動垃圾回收器回收垃圾 finalize() 如果一個對象被回收器回收的時候,會先調用對象的finalize()方法* */public static void main(String[] args) {// TODO Auto-generated method stubint[] srcArr= {10,12,14,16,19};//把srcArr數組的元素拷貝到destArr數組中int[] destArr=new int[4];System.arraycopy(srcArr, 1, destArr, 0, 4);//System.exit(0); //jvm退出... 0或者非0的數據都可以退出jvm。對于用戶而言沒有任何區(qū)別System.out.println("目標數組的元素:"+Arrays.toString(destArr));System.out.println("當前的系統(tǒng)時間是:"+System.currentTimeMillis());for (int i=0;i<4;i++) {new Person("狗娃"+i);System.gc(); //建議趕快啟動垃圾回收器回收 }}} class Person{String name;public Person(String name) {this.name=name;}@Overrideprotected void finalize() throws Throwable {// TODO Auto-generated method stubsuper.finalize();System.out.println(this.name+"被回收了");} }結果: 目標數組的元素:[12, 14, 16, 19] 當前的系統(tǒng)時間是:1549627330079 狗娃0被回收了 狗娃2被回收了 狗娃3被回收了 狗娃1被回收了

?    getenv(String name)   根據環(huán)境變量的名字獲取環(huán)境變量

System.out.println("環(huán)境變量:"+System.getenv("JAVA_HOME"));結果: 環(huán)境變量:D:\JAVA\jdk\

    getProperties()      獲取當前的系統(tǒng)所有的屬性

    getProperty(String key)   根據系統(tǒng)的屬性名獲取對應的屬性值(獲取一個屬性)

//Properties properties=System.getProperties();//properties.list(System.out);String value=System.getProperty("os.name");System.out.println("當前系統(tǒng):"+value);結果: 當前系統(tǒng):Windows 10

?

?

Runtime類    該類主要代表了應用程序的運行環(huán)境   

    getRuntime()         返回當前應用程序的運行環(huán)境對象
    exec(String command)      根據指定的路徑執(zhí)行對應的可執(zhí)行文件

import java.io.IOException;/*getRuntime() 返回當前應用程序的運行環(huán)境對象exec(String command) 根據指定的路徑執(zhí)行對應的可執(zhí)行文件*/ public class Demo2 {public static void main(String[] args) throws IOException, InterruptedException {// TODO Auto-generated method stubRuntime runtime=Runtime.getRuntime();Process process=runtime.exec("C:\\Windows\\notepad.exe");Thread.sleep(3000); //讓當前程序停止3秒 process.destroy();}}結果: 打開記事本,三秒之后關閉

      freeMemory()       返回jvm空閑的內存,以字節(jié)為單位。
      maxMemory()        返回 Java 虛擬機試圖使用的最大內存量
      totalMemory()        返回 Java 虛擬機中的內存總量

public static void main(String[] args) throws IOException, InterruptedException {// TODO Auto-generated method stubRuntime runtime=Runtime.getRuntime();System.out.println("jvm空閑的內存量:"+runtime.freeMemory());System.out.println("Java 虛擬機試圖使用的最大內存量"+runtime.maxMemory());System.out.println("Java 虛擬機的內存總量"+runtime.totalMemory());}結果: jvm空閑的內存量:124484880 Java 虛擬機試圖使用的最大內存量2000683008 Java 虛擬機的內存總量125829120

?

日期類Date

使用Calendar.getInstance()獲取Calendar對象

import java.util.Calendar; import java.util.Date; public class Demo3 {public static void main(String[] args) {// TODO Auto-generated method stub//Date date=new Date(); //獲取當前的系統(tǒng)時間//System.out.println("年份:"+date.getYear());//已經過時,不推薦使用Calendar calendar=Calendar.getInstance(); //獲取當前的系統(tǒng)時間System.out.println("年:"+calendar.get(Calendar.YEAR));System.out.println("月:"+(calendar.get(Calendar.MONTH)+1));System.out.println("日:"+calendar.get(Calendar.DATE));System.out.println("時:"+calendar.get(Calendar.HOUR_OF_DAY));System.out.println("分:"+calendar.get(Calendar.MINUTE));System.out.println("秒:"+calendar.get(Calendar.SECOND));}}結果: 年:2019 月:2 日:12 時:9 分:11 秒:20

日期格式化類SimpleDateFormat

作用:

  • 可以把日期轉換成指定格式的字符串  format()
  • 可以把一個字符串轉換成對應的日期? ? ? ?parse()
  • import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; public class Demo3 {public static void main(String[] args) throws ParseException {// TODO Auto-generated method stub//Date date=new Date(); //獲取當前的系統(tǒng)時間//System.out.println("年份:"+date.getYear());//顯示當前的系統(tǒng)時間:2019年2月12日 xx時xx分xx秒/*日期格式化類SimpleDateFormat* 作用1:可以把日期轉換成指定格式的字符串 format()* 作用2:可以把一個字符串轉換成對應的日期 parse()* */Date date=new Date();SimpleDateFormat dateFormat=new SimpleDateFormat(); //使用了默認的格式創(chuàng)建了一個日期格式化對象String time=dateFormat.format(date);System.out.println("當前的系統(tǒng)時間:"+time);SimpleDateFormat dateFormat2=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");time=dateFormat2.format(date);System.out.println("當前的系統(tǒng)時間:"+time);String birthday="1999年11月1日 19:27:35";Date date2=dateFormat2.parse(birthday); //注意:指定的字符串格式必須要與SimpleDateFormat的模式要一致,空格個數也要考慮 System.out.println(date2);}}結果: 當前的系統(tǒng)時間:2019/2/12 上午10:55 當前的系統(tǒng)時間:2019年02月12日 10:55:31 Mon Nov 01 19:27:35 CST 1999

    Math類(數學類)    主要是提供了很多的數學公式

    abs(double a)      ? ? 獲取絕對值
    ceil(double a)        向上取整
    floor(double a)      ? ?向下取整
    round(float a)        四舍五入
    random()          產生一個隨機數,返回帶正號的?double?值,該值大于等于?0.0?且小于?1.0

    public static void main(String[] args) {// TODO Auto-generated method stubSystem.out.println("絕對值:"+Math.abs(-3));System.out.println("向上取整:"+Math.ceil(3.14));System.out.println("向上取整:"+Math.ceil(-3.14));System.out.println("向下取整:"+Math.floor(3.14));System.out.println("向下取整:"+Math.floor(-3.14));System.out.println("四舍五入:"+Math.round(3.54));System.out.println("四舍五入:"+Math.round(3.49));System.out.println("隨機數:"+Math.random());}結果: 絕對值:3 向上取整:4.0 向上取整:-3.0 向下取整:3.0 向下取整:-4.0 四舍五入:4 四舍五入:3 隨機數:0.6458472762144221

    隨機數類:(Random類)

    import java.util.Random;/*Random類 隨機數類*/ public class Demo5 {public static void main(String[] args) {// TODO Auto-generated method stubRandom random=new Random();int randomNum=random.nextInt(10)+1;//產生的隨機數是1-10之間的System.out.println("隨機數:"+randomNum);}}結果: 隨機數:2

    注意:隨機數產生的區(qū)間是根據所給區(qū)間? ?左閉右開? ?的,也就是包含左邊的臨界值,不包含右邊的

    需求:編寫一個函數隨機產生四位的驗證碼。

    import java.util.Random;/*Random類 隨機數類*/ public class Demo5 {public static void main(String[] args) {// TODO Auto-generated method stub/*Random random=new Random();int randomNum=random.nextInt(10)+1;//產生的隨機數是1-10之間的System.out.println("隨機數:"+randomNum);*/char[] arr= {'中','國','傳','a','Q','f','B'};StringBuilder sb=new StringBuilder();Random random=new Random();//需要四個隨機數,通過隨機數獲取字符數組中的字符for (int i=0;i<4;i++) {int index=random.nextInt(arr.length);//產生的隨機數必須是數組的索引值范圍之內的 sb.append(arr[index]);}//String str=sb.toString();//System.out.println("驗證碼為:"+str);System.out.println("驗證碼為:"+sb);}}結果: 驗證碼為:QB傳B

    ?

    進程:正在執(zhí)行的程序稱作為一個進程,進程負責了內存空間的劃分

    Windows號稱是多任務的操作系統(tǒng),那么Windows是同時運行多個應用程序嗎?

        從宏觀的角度:Windows確實是在同時運行多個應用程序

        從微觀的角度:cpu是做了一個快速切換執(zhí)行的動作,由于速度太快,所以我們感覺不到在切換而已。

    線程:線程在一個進程中負責了代碼的執(zhí)行,就是進程中一個執(zhí)行路徑

    多線程:在一個進程中有多個線程同時在執(zhí)行不同的任務

    疑問:我們以前沒有學過線程,而線程負責代碼的執(zhí)行,為什么代碼可以執(zhí)行呢?

        任何一個Java程序,jvm在運行的時候都會創(chuàng)建一個main線程執(zhí)行main方法中的所有代碼

    一個Java應用程序至少有兩個線程,一個是主線程負責了main方法的執(zhí)行,一個是垃圾回收器線程,負責了回收垃圾

    多線程的好處:

  • 解決了一個進程能同時執(zhí)行多個任務的問題
  • 提高了資源的利用率
  • 多線程的弊端:

  • 增加了cpu的負擔
  • 降低了一個進程中線程的執(zhí)行概率
  • 引發(fā)了線程安全問題
  • 出現了死鎖現象
  • 如何創(chuàng)建多線程:

        創(chuàng)建線程的方式:

          方式一:

  • 自定義一個類繼承Thread類
  • 重寫Thread類的run方法,把自定義線程的任務寫在run方法中
    • 重寫run方法的目的是什么呢?
      • 每個線程都有自己的任務代碼,jvm創(chuàng)建的主線程的任務代碼就是main方法中的所有代碼,自定義線程的任務代碼就寫在run方法中,自定義線程負責了run方法中的代碼
  • 調用Thread的子類對象,并且調用start方法開啟線程
    • 注意:一個線程一旦開啟,那么線程就會執(zhí)行run方法中的代碼,run方法千萬不能直接調用,直接調用run方法就相當于調用了一個普通的方法而已
  • public class Demo6 extends Thread{@Override //把自定義線程的任務寫在run方法中public void run() {// TODO Auto-generated method stubfor (int i=0;i<10;i++) {System.out.println("自定義線程:"+i);}super.run();}public static void main(String[] args) {// TODO Auto-generated method stub//創(chuàng)建了自定義的線程對象Demo6 d=new Demo6();//調用start方法啟動線程 d.start();for (int i=0;i<10;i++) {System.out.println("main線程:"+i);}}}結果: main線程:0 自定義線程:0 main線程:1 自定義線程:1 main線程:2 自定義線程:2 自定義線程:3 自定義線程:4 main線程:3 main線程:4 main線程:5 main線程:6 main線程:7 main線程:8 main線程:9 自定義線程:5 自定義線程:6 自定義線程:7 自定義線程:8 自定義線程:9

    ?需求:模擬QQ視頻與聊天同時進行

    public class Demo7 {public static void main(String[] args) {// TODO Auto-generated method stubTalkThread talkThread=new TalkThread();talkThread.start();VideoThraead videoThread=new VideoThraead();videoThread.start();}} class VideoThraead extends Thread{@Overridepublic void run() {// TODO Auto-generated method stubint i=0;while (i++<50) {System.out.println("視頻");}super.run();} } class TalkThread extends Thread{@Overridepublic void run() {// TODO Auto-generated method stubint i=0;while (i++<50) {System.out.println("聊天");}super.run();} }結果: 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 視頻 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天 聊天

    線程的生命周期圖

    線程常用的方法:

    Thread(String name)???? 初始化線程的名字

    ?getName()???????????? 返回線程的名字

    ?setName(String name)??? 設置線程對象名

    ?sleep()???????????????? 線程睡眠指定的毫秒數。  靜態(tài)的方法,哪個線程執(zhí)行了sleep方法代碼那么就是哪個線程睡眠

    ?getPriority()???????????? 返回當前線程對象的優(yōu)先級?? 默認線程的優(yōu)先級是5,優(yōu)先級的數字越大,優(yōu)先級越高,優(yōu)先級的范圍是1~10,注意:線程的優(yōu)先級高,并不意味著就一定先執(zhí)行,只是搶到cpu的概率更大了

    ?setPriority(int newPriority) 設置線程的優(yōu)先級??? 雖然設置了線程的優(yōu)先級,但是具體的實現取決于底層的操作系統(tǒng)的實現(最大的優(yōu)先級是10 ,最小的1 , 默認是5)。

    ?currentThread()????? 返回CPU正在執(zhí)行的線程的對象?    該方法是一個靜態(tài)的方法,哪個線程執(zhí)行了currentThread()代碼就返回哪個線程的對象

    public class Demo8 extends Thread{public Demo8() {}public Demo8(String name) {super(name); //調用了Thread類的一個參數的構造方法 }@Overridepublic void run() {// TODO Auto-generated method stubfor (int i=0;i<10;i++) {System.out.println(this.getName()+i);try {Thread.sleep(100);//這里只能捕獲,不能拋出,因為其父類Thread的run方法并沒有拋出異常,子類重寫時拋出的異常類型要小于或等于父類拋出的異常} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}}super.run();}public static void main(String[] args) throws InterruptedException {// TODO Auto-generated method stub//創(chuàng)建了一個線程對象Demo8 d=new Demo8("狗娃");d.sleep(1000);d.setName("鐵蛋");//d.setName("鐵蛋");//設置線程的名字System.out.println("線程的名字:"+d.getName());d.start();}}結果: 線程的名字:鐵蛋 鐵蛋0 鐵蛋1 鐵蛋2 鐵蛋3 鐵蛋4 鐵蛋5 鐵蛋6 鐵蛋7 鐵蛋8 鐵蛋9 先出來第一二行,然后每隔0.1秒出來一行 public class Demo8 extends Thread{public Demo8() {}public Demo8(String name) {super(name); //調用了Thread類的一個參數的構造方法 }@Overridepublic void run() {// TODO Auto-generated method stubSystem.out.println("this:"+this);System.out.println("當前線程對象:"+Thread.currentThread());for (int i=0;i<10;i++) {System.out.println(this.getName()+i);System.out.println(Thread.currentThread().getName()+i);/*try {Thread.sleep(100);//這里只能捕獲,不能拋出,因為其父類Thread的run方法并沒有拋出異常,子類重寫時拋出的異常類型要小于或等于父類拋出的異常} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}*/}}public static void main(String[] args) throws InterruptedException {// TODO Auto-generated method stub//創(chuàng)建了一個線程對象Demo8 d=new Demo8("狗娃");System.out.println("自定義線程的優(yōu)先級:"+d.getPriority());System.out.println("主線程的優(yōu)先級:"+Thread.currentThread().getPriority());//d.sleep(1000);d.setName("鐵蛋");//d.setName("鐵蛋");//設置線程的名字System.out.println("線程的名字:"+d.getName());d.setPriority(10);d.start();for (int i=0;i<10;i++) {System.out.println(Thread.currentThread().getName()+i);}Thread mainThread=Thread.currentThread();System.out.println("主線程的名字:"+mainThread.getName());}}結果: 自定義線程的優(yōu)先級:5 主線程的優(yōu)先級:5 線程的名字:鐵蛋 main0 main1 main2 main3 main4 this:Thread[鐵蛋,10,main] 當前線程對象:Thread[鐵蛋,10,main] 鐵蛋0 鐵蛋0 鐵蛋1 鐵蛋1 鐵蛋2 鐵蛋2 鐵蛋3 鐵蛋3 鐵蛋4 鐵蛋4 鐵蛋5 鐵蛋5 鐵蛋6 鐵蛋6 鐵蛋7 鐵蛋7 鐵蛋8 鐵蛋8 鐵蛋9 鐵蛋9 main5 main6 main7 main8 main9 主線程的名字:main

    需求:模擬三個窗口在售50張票

    public class Demo9 {public static void main(String[] args) {// TODO Auto-generated method stub//創(chuàng)建三個線程對象,模擬三個窗口SaleTicket thread1=new SaleTicket("窗口1");SaleTicket thread2=new SaleTicket("窗口2");SaleTicket thread3=new SaleTicket("窗口3");//開啟線程售票 thread1.start();thread2.start();thread3.start();}} class SaleTicket extends Thread{static int num=50;//票數 不加static的時候是非靜態(tài)的成員變量,非靜態(tài)的成員變量數據是在每個對象中都會維護一份數據的。所以會出現三個窗口賣了150張票的情況public SaleTicket() {}public SaleTicket(String name) {// TODO Auto-generated constructor stubsuper(name);}@Overridepublic void run() {// TODO Auto-generated method stubwhile (true) {if (num>0) {System.out.println(Thread.currentThread().getName()+"售出了第"+num+"號票");num--;}else {System.out.println("售罄了...");break;}}//super.run(); } }

    問題1:50張票售了150次

    可以向票數上加static使其成為靜態(tài)成員變量來解決

    問題2:出現了線程安全問題

    出現線程安全問題的根本原因:

  • 存在兩個或者兩個以上的線程對象,而且線程之間共享著一個資源
  • 有多個語句操作了共享資源
  • 線程安全問題的解決方案:sun提供了線程同步機制讓我們解決這類問題的

    Java線程同步機制的方式:

        方式一:同步代碼塊

          同步代碼塊的格式:

            synchronized(鎖對象){

              需要被同步的代碼...

            }

    同步代碼塊要注意的事項:

  • 任意的一個對象都可以作為鎖對象
  • 在同步代碼塊中調用了sleep方法并不是釋放鎖對象的,也就是不會改變鎖對象的開關狀態(tài),就像你睡覺鎖著門,別人也進不來
  • 只有真正存在線程安全問題的時候才使用同步代碼塊,否則會降低效率的
  • 多線程操作的鎖對象必須是唯一共享的,否則無效。
  • public class Demo9 {public static void main(String[] args) {// TODO Auto-generated method stub//創(chuàng)建三個線程對象,模擬三個窗口SaleTicket thread1=new SaleTicket("窗口1");SaleTicket thread2=new SaleTicket("窗口2");SaleTicket thread3=new SaleTicket("窗口3");//開啟線程售票 thread1.start();thread2.start();thread3.start();}} class SaleTicket extends Thread{static int num=50;//票數 不加static的時候是非靜態(tài)的成員變量,非靜態(tài)的成員變量數據是在每個對象中都會維護一份數據的。所以會出現三個窗口賣了150張票的情況static Object o=new Object();//為什么要加static呢public SaleTicket() {}public SaleTicket(String name) {// TODO Auto-generated constructor stubsuper(name);}@Overridepublic void run() {// TODO Auto-generated method stubwhile (true) {//同步代碼塊synchronized (o) {//可以使用字符串 "鎖" ,這是最簡單的鎖對象,因為它在字符串常量池中if (num>0) {System.out.println(Thread.currentThread().getName()+"售出了第"+num+"號票");num--;}else {System.out.println("售罄了...");break;}}}//super.run(); } }結果: 窗口1售出了第50號票 窗口1售出了第49號票 窗口1售出了第48號票 窗口1售出了第47號票 窗口3售出了第46號票 窗口3售出了第45號票 窗口3售出了第44號票 窗口3售出了第43號票 窗口3售出了第42號票 窗口3售出了第41號票 窗口3售出了第40號票 窗口3售出了第39號票 窗口3售出了第38號票 窗口2售出了第37號票 窗口2售出了第36號票 窗口2售出了第35號票 窗口2售出了第34號票 窗口2售出了第33號票 窗口2售出了第32號票 窗口2售出了第31號票 窗口2售出了第30號票 窗口2售出了第29號票 窗口2售出了第28號票 窗口2售出了第27號票 窗口2售出了第26號票 窗口2售出了第25號票 窗口2售出了第24號票 窗口2售出了第23號票 窗口2售出了第22號票 窗口2售出了第21號票 窗口2售出了第20號票 窗口2售出了第19號票 窗口2售出了第18號票 窗口2售出了第17號票 窗口2售出了第16號票 窗口2售出了第15號票 窗口2售出了第14號票 窗口2售出了第13號票 窗口2售出了第12號票 窗口2售出了第11號票 窗口2售出了第10號票 窗口2售出了第9號票 窗口2售出了第8號票 窗口2售出了第7號票 窗口2售出了第6號票 窗口2售出了第5號票 窗口2售出了第4號票 窗口2售出了第3號票 窗口2售出了第2號票 窗口2售出了第1號票 售罄了... 售罄了... 售罄了...

        方式二:同步函數

    轉載于:https://www.cnblogs.com/zhangwugai/p/10354537.html

    總結

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

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