導航:首頁 > 編程語言 > java程序開發範例

java程序開發範例

發布時間:2025-03-12 01:01:28

『壹』 java經典編程300例的目錄

第1章 Java語言概述 1
實例001 輸出「Hello World」 2
實例002 輸出控制台傳遞的參數 2
實例003 輸出由「*」組成的三角形 3
實例004 輸出符號表情 5
第2章 Eclipse開發工具 6
實例005 下載並運行Eclipse工具 7
實例006 為Eclipse安裝漢化包 8
實例007 使用Eclipse注釋代碼 10
實例008 使用Eclipse格式化代碼 11
實例009 安裝WindowBuilder插件 12
實例010 開發計算器界面 14
第3章 Java語言基礎 15
實例011 輸出錯誤信息與調試信息 16
實例012 從控制台接收輸入字元 16
實例013 重定向輸出流實現程序日誌 17
實例014 自動類型轉換與強制類型轉換 19
實例015 加密可以這樣簡單(位運算) 20
實例016 用三元運算符判斷奇數和偶數 21
實例017 不用乘法運算符實現2×16 22
實例018 實現兩個變數的互換
(不藉助第3個變數) 23
第4章 流程式控制制 25
實例019 判斷某一年是否為閏年 26
實例020 驗證登錄信息的合法性 27
實例021 為新員工分配部門 28
實例022 用switch語句根據消費
金額計算折扣 29
實例023 判斷用戶輸入月份的季節 31
實例024 使用while循環語句與自增
運算符循環遍歷數組 33
實例025 使用for循環輸出楊輝三角形 34
實例026 使用嵌套循環在控制台上
輸出九九乘法表 35
實例027 使用while循環計算1+
1/2!+1/3!…1/20! 36
實例028 使用for循環輸出空心的菱形 38
實例029 終止循環體 39
實例030 循環體的過濾器 41
第5章 數組及其常用操作 43
實例031 獲取一維數組的最小值 44
實例032 將二維數組中的行列互換 45
實例033 利用數組隨機抽取幸運觀眾 47
實例034 用數組設置JTable表格的
列名與列寬 49
實例035 使用按鈕控制項數組實現
計算器界面 51
實例036 通過復選框控制項數組實現
添加多個復選框控制項 52
實例037 使用選擇排序法對數組排序 53
實例038 使用冒泡排序法對數組排序 55
實例039 使用快速排序法對數組排序 57
實例040 使用直接插入法對數組排序 59
實例041 使用sort()方法對數組排序 61
實例042 反轉數組中元素的順序 63
第6章 面向對象入門 65
實例043 自定義圖書類 66
實例044 溫度單位轉換工具 67
實例045 成員變數的默認初始化值 68
實例046 單例模式的應用 69
實例047 漢諾塔問題求解 70
實例048 編寫同名的方法 71
實例049 構造方法的應用 72
實例050 統計圖書的銷售量 73
實例051 兩只完全相同的寵物 74
實例052 重新計算對象的哈希碼 76
實例053 使用字元串輸出對象 77
實例054 Java對象的假克隆 78
實例055 Java對象的淺克隆 80
實例056 Java對象的深克隆 82
實例057 序列化與對象克隆 84
實例058 深克隆效率的比較 87
第7章 面向對象進階 89
實例059 經理與員工的差異 90
實例060 重寫父類中的方法 92
實例061 計算幾何圖形的面積 93
實例062 簡單的汽車銷售商場 95
實例063 使用Comparable介面自定
義排序 96
實例064 策略模式的簡單應用 98
實例065 適配器模式的簡單應用 100
實例066 普通內部類的簡單應用 102
實例067 局部內部類的簡單應用 103
實例068 匿名內部類的簡單應用 104
實例069 靜態內部類的簡單應用 105
實例070 實例化Class類的幾種方式 107
實例071 查看類的聲明 108
實例072 查看類的成員 110
實例073 查看內部類信息 112
實例074 動態設置類的私有域 113
實例075 動態調用類中方法 115
實例076 動態實例化類 116
實例077 創建長度可變的數組 117
實例078 利用反射重寫toString()方法 119
第8章 字元串與包裝類 121
實例079 將數字格式化為貨幣字元串 122
實例080 貨幣金額大寫格式 123
實例081 String類格式化當前日期 125
實例082 字元串大小寫轉換 126
實例083 字元與Unicode碼的轉換 128
實例084 判斷用戶名是否正確 129
實例085 用戶名排序 130
實例086 判斷網頁請求與FTP請求 132
實例087 判斷文件類型 133
實例088 判斷字元串是否為數字 135
實例089 驗證IP地址的有效性 136
實例090 鑒別非法電話號碼 137
實例091 將字元串轉換成整數 139
實例092 整數進制轉換器 140
實例093 獲取字元串中漢字的個數 141
實例094 批量替換某一類字元串 142
實例095 查看數字的取值范圍 144
實例096 ASCII編碼查看器 145
實例097 判斷手機號的合法性 146
實例098 用字元串構建器追加字元 147
實例099 去掉字元串中的所有空格 148
實例100 Double類型的比較 149
第9章 Java集合類框架 151
範例101 用動態數組保存學生姓名 152
實例102 用List集合傳遞學生信息 153
實例103 Map集合二級聯動 155
實例104 不重復隨機數組排序 157
實例105 for循環遍歷ArrayList 159
實例106 Iterator遍歷ArrayList 159
實例107 ListIterator逆序遍歷ArrayList 160
實例108 製作電子詞典 161
實例109 製作手機電話簿 162
第10章 常用數學工具類 164
實例110 角度和弧度的轉換 165
實例111 三角函數的使用 166
實例112 反三角函數的使用 167
實例113 雙曲函數的使用 168
實例114 指數與對數運算 169
實例115 高精度整數運算 170
實例116 高精度浮點運算 171
實例117 七星彩號碼生成器 173
實例118 大樂透號碼生成器 174
第11章 錯誤處理 177
實例119 算數異常 178
實例120 數組下標越界異常 179
實例121 空指針異常 180
實例122 類未發現異常 181
實例123 非法訪問異常 182
實例124 文件未發現異常 183
實例125 資料庫操作異常 184
實例126 方法中拋出異常 185
實例127 方法上拋出異常 186
實例128 自定義異常類 187
實例129 捕獲單個異常 188
實例130 捕獲多個異常 189
第12章 輸入/輸出 191
實例131 顯示指定類型的文件 192
實例132 以樹結構顯示文件路徑 193
實例133 查找替換文本文件內容 194
實例134 設置Windows系統的文件
屬性 195
實例135 文件批量重命名 196
實例136 快速批量移動文件 197
實例137 刪除文件夾中的.tmp文件 198
實例138 將圖片文件保存到資料庫 199
實例139 從資料庫讀取圖片文件 200
實例140 窗體動態載入磁碟文件 201
實例141 刪除文件夾中所有文件 202
實例142 創建磁碟索引文件 208
實例143 控制台記錄器 205
實例144 防止創建多個字元串對象 206
實例145 合並多個文本文件 207
實例146 對大文件實現分割處理 208
實例147 將分割後的文件重新合並 209
實例148 讀取屬性文件單個屬性值 210
實例149 向屬性文件中添加信息 211
實例150 在復制文件時使用進度條 212
實例151 從XML文件中讀取數據 213
實例152 讀取Jar文件屬性 214
實例153 電子通訊錄 215
實例154 批量復制指定擴展名文件 217
實例155 分類保存文件 218
實例156 搜索指定文件夾中的文件 219
實例157 實現文件鎖定功能 220
實例158 簡單的投票軟體 221
實例159 壓縮所有文本文件 222
實例160 將壓縮包解壓到指定文件夾 223
實例161 壓縮所有子文件夾 225
實例162 深層文件夾壓縮包的釋放 226
實例163 解決壓縮包中文亂碼 227
實例164 Apache實現文件解壓縮 228
實例165 把窗體壓縮成ZIP文件 229
實例166 解壓縮Java對象 230
實例167 文件壓縮為RAR文檔 231
實例168 解壓縮RAR壓縮包 233
實例169 為RAR壓縮包添加註釋 234
實例170 獲取壓縮包詳細文件列表 235
實例171 從RAR壓縮包中刪除文件 237
實例172 在壓縮文件中查找字元串 238
實例173 重命名RAR壓縮包中文件 239
實例174 創建自解壓RAR壓縮包 240
第13章 枚舉類型與泛型 242
實例175 查看枚舉類型的定義 243
實例176 枚舉類型的基本特性 244
實例177 增加枚舉元素的信息 245
實例178 選擇合適的枚舉元素 246
實例179 高效的枚舉元素集合 248
實例180 高效的枚舉元素映射 249
實例181 使用枚舉介面遍歷元素 250
實例182 使用泛型實現棧結構 251
實例183 自定義泛型化數組類 253
實例184 泛型方法與數據查詢 254
實例185 使用通配符增強泛型 256
實例186 泛型化的折半查找法 257
第14章 Swing入門 259
實例187 從上次關閉位置啟動窗體 260
實例188 始終在桌面最頂層顯示窗體 261
實例189 設置窗體大小 262
實例190 根據桌面大小調整窗體大小 263
實例191 自定義最大化、最小化和
關閉按鈕 265
實例192 禁止改變窗體的大小 267
實例193 指定窗體標題欄圖標 267
實例194 設置閃爍的標題欄 269
實例195 實現帶背景圖片的窗體 270
實例196 背景為漸變色的主界面 271
實例197 隨機更換窗體背景 273
實例198 橢圓形窗體界面 275
實例199 鑽石形窗體 276
實例200 創建透明窗體 277
實例201 信息提示對話框 278
實例202 設置信息提示對話框的圖標 279
實例203 指定打開對話框的文件類型 280
實例204 為保存對話框設置默認文件名 282
實例205 支持圖片預覽的文件選
擇對話框 283
實例206 顏色選擇對話框 285
實例207 信息輸入對話框 286
實例208 定製信息對話框 287
實例209 攔截事件的玻璃窗格 289
實例210 簡單的每日提示信息 290
實例211 震動效果的提示信息 292
實例212 製作圓形布局管理器 293
實例213 製作階梯布局管理器 295
實例214 密碼域控制項簡單應用 296
實例215 文本域設置背景圖片 297
實例216 文本區設置背景圖片 298
實例217 簡單的字元統計工具 299
實例218 能預覽圖片的復選框 300
實例219 簡單的投票計數軟體 301
實例220 單選按鈕的簡單應用 302
實例221 能顯示圖片的組合框 303
實例222 使用滑塊來選擇日期 305
實例223 模仿記事本的菜單欄 308
實例224 自定義縱向的菜單欄 309
實例225 復選框與單選按鈕菜單項 311
實例226 包含圖片的彈出菜單 312
實例227 工具欄的實現與應用 314
實例228 修改列表項顯示方式 315
實例229 列表項與提示信息 316
實例230 表頭與列的高度設置 317
實例231 調整表格各列的寬度 319
實例232 設置表格的選擇模式 321
實例233 為表頭增添提示信息 323
實例234 單元格的粗粒度排序 325
實例235 實現表格的查找功能 326
實例236 應用網格布局設計計算
器窗體 327
第15章 多線程 329
實例237 查看線程的運行狀態 330
實例238 查看JVM中的線程名 331
實例239 查看和修改線程優先順序 333
實例240 休眠當前線程 335
實例241 終止指定線程 336
實例242 線程的插隊運行 337
實例243 使用方法實現線程同步 339
實例244 使用特殊域變數實現線程同步 341
實例245 簡單的線程通信 342
實例246 新建有返回值的線程 344
實例247 使用線程池優化多線程編程 346
實例248 哲學家的就餐問題 348
第16章 網路通信 350
實例249 獲得內網的所有IP地址 351
實例250 獲取網路資源的大小 352
實例251 解析網頁中的內容 354
實例252 網路資源的單線程下載 355
實例253 網路資源的多線程下載 357
實例254 下載網路資源的斷點續傳 359
實例255 建立伺服器套接字 362
實例256 建立客戶端套接字 363
實例257 設置等待連接的超時時間 364
實例258 獲得Socket信息 365
實例259 接收和發送Socket信息 367
實例260 關閉Socket緩沖 369
實例261 使用Socket通信 371
實例262 防止Socket傳遞漢字亂碼 375
實例263 使用Socket傳遞對象 377
實例264 使用Socket傳輸圖片 379
實例265 使用Socket傳輸音頻 381
實例266 使用Socket傳輸視頻 384
實例267 一個伺服器與一個客戶端
通信 385
實例268 一個伺服器與多個客戶端
通信 387
實例269 客戶端一對多通信 389
實例270 客戶端一對一通信 391
實例271 基於Socket的資料庫編程 393
實例272 使用Proxy創建代理伺服器 396
實例273 使用ProxySelector選擇
代理伺服器 397
實例274 聊天室伺服器端 399
實例275 聊天室客戶端 401
第17章 資料庫操作 405
實例276 JDBC連接MySQL資料庫 406
實例277 連接SQL Server 2005資料庫 407
實例278 JDBC連接Oracle資料庫 408
實例279 獲取SQL Server指定數據
庫中的數據表信息 409
實例280 獲取MySQL指定資料庫
中的數據表名稱 411
實例281 查看數據表結構 412
實例282 動態維護投票資料庫 414
實例283 SQL Server數據備份 416
實例284 SQL Server數據恢復 419
實例285 MySQL數據備份 422
實例286 MySQL數據恢復 424
實例287 動態附加資料庫 425
實例288 生成SQL資料庫腳本 426
實例289 表中欄位的描述信息 429
實例290 將員工信息添加到數據表 430
實例291 添加數據時使用數據驗證 431
實例292 插入用戶登錄日誌信息 432
實例293 生成有規律的編號 433
實例294 生成無規律的編號 435
實例295 插入數據時過濾危險字元 436
實例296 復選框保存到資料庫 437
實例297 把數據復制到另一張表中 438
實例298 批量插入數據 439
實例299 更新指定記錄 440
實例300 在刪除數據時給出提示信息 442

『貳』 Java 下面的範例問什麼運行不了啊也沒有報錯。

雖然代碼寫的不規范,但是沒有什麼錯誤啊,我直接拷貝你的代碼,然後運行也沒有錯。

我是這么做的:

1、在桌面上建立一個person.java,把你寫的person的代碼粘貼進去;

2、同第一步,建立student.java,粘貼student代碼;建立test.java,粘貼test代碼;

3、依次編譯person.java,student.java,test.java

4、運行test,至此結束,程序沒有出現任何編譯和運行錯誤,正常列印出了要求列印的信息

『叄』 如何在 Java 中正確使用 wait,notify 和 notifyAll

wait, notify 和 notifyAll,這些在多線程中被經常用到的保留關鍵字,在實際開發的時候很多時候卻並沒有被大家重視。本文對這些關鍵字的使用進行了描述。

在 Java 中可以用 wait、notify 和 notifyAll
來實現線程間的通信。。舉個例子,如果你的Java程序中有兩個線程——即生產者和消費者,那麼生產者可以通知消費者,讓消費者開始消耗數據,因為隊列緩
沖區中有內容待消費(不為空)。相應的,消費者可以通知生產者可以開始生成更多的數據,因為當它消耗掉某些數據後緩沖區不再為滿。

我們可以利用wait()來讓一個線程在某些條件下暫停運行。例如,在生產者消費者模型中,生產者線程在緩沖區為滿的時候,消費者在緩沖區為空的時
候,都應該暫停運行。如果某些線程在等待某些條件觸發,那當那些條件為真時,你可以用 notify 和 notifyAll
來通知那些等待中的線程重新開始運行。不同之處在於,notify 僅僅通知一個線程,並且我們不知道哪個線程會收到通知,然而 notifyAll
會通知所有等待中的線程。換言之,如果只有一個線程在等待一個信號燈,notify和notifyAll都會通知到這個線程。但如果多個線程在等待這個信
號燈,那麼notify只會通知到其中一個,而其它線程並不會收到任何通知,而notifyAll會喚醒所有等待中的線程。

在這篇文章中你將會學到如何使用 wait、notify 和 notifyAll 來實現線程間的通信,從而解決生產者消費者問題。如果你想要更深入地學習Java中的多線程同步問題,我強烈推薦閱讀Brian Goetz所著的《Java Concurrency in Practice | Java 並發實踐》,不讀這本書你的 Java 多線程征程就不完整哦!這是我最向Java開發者推薦的書之一。

如何使用Wait

盡管關於wait和notify的概念很基礎,它們也都是Object類的函數,但用它們來寫代碼卻並不簡單。如果你在面試中讓應聘者來手寫代碼,
用wait和notify解決生產者消費者問題,我幾乎可以肯定他們中的大多數都會無所適從或者犯下一些錯誤,例如在錯誤的地方使用
synchronized 關鍵詞,沒有對正確的對象使用wait,或者沒有遵循規范的代碼方法。說實話,這個問題對於不常使用它們的程序員來說確實令人感覺比較頭疼。

第一個問題就是,我們怎麼在代碼里使用wait()呢?因為wait()並不是Thread類下的函數,我們並不能使用
Thread.call()。事實上很多Java程序員都喜歡這么寫,因為它們習慣了使用Thread.sleep(),所以他們會試圖使用wait()

來達成相同的目的,但很快他們就會發現這並不能順利解決問題。正確的方法是對在多線程間共享的那個Object來使用wait。在生產者消費者問題中,這
個共享的Object就是那個緩沖區隊列。

第二個問題是,既然我們應該在synchronized的函數或是對象里調用wait,那哪個對象應該被synchronized呢?答案是,那個

你希望上鎖的對象就應該被synchronized,即那個在多個線程間被共享的對象。在生產者消費者問題中,應該被synchronized的就是那個
緩沖區隊列。(我覺得這里是英文原文有問題……本來那個句末就不應該是問號不然不太通……)

永遠在循環(loop)里調用 wait 和 notify,不是在 If 語句

現在你知道wait應該永遠在被synchronized的背景下和那個被多線程共享的對象上調用,下一個一定要記住的問題就是,你應該永遠在
while循環,而不是if語句中調用wait。因為線程是在某些條件下等待的——在我們的例子里,即「如果緩沖區隊列是滿的話,那麼生產者線程應該等
待」,你可能直覺就會寫一個if語句。但if語句存在一些微妙的小問題,導致即使條件沒被滿足,你的線程你也有可能被錯誤地喚醒。所以如果你不在線程被喚

醒後再次使用while循環檢查喚醒條件是否被滿足,你的程序就有可能會出錯——例如在緩沖區為滿的時候生產者繼續生成數據,或者緩沖區為空的時候消費者
開始小號數據。所以記住,永遠在while循環而不是if語句中使用wait!我會推薦閱讀《Effective Java》,這是關於如何正確使用wait和notify的最好的參考資料。

基於以上認知,下面這個是使用wait和notify函數的規范代碼模板:
// The standard idiom for calling the wait method in Java synchronized (sharedObject) { while (condition) { sharedObject.wait(); // (Releases lock, and reacquires on wakeup) } // do action based upon condition e.g. take or put into queue }

就像我之前說的一樣,在while循環里使用wait的目的,是在線程被喚醒的前後都持續檢查條件是否被滿足。如果條件並未改變,wait被調用之前notify的喚醒通知就來了,那麼這個線程並不能保證被喚醒,有可能會導致死鎖問題。

Java wait(), notify(), notifyAll() 範例

下面我們提供一個使用wait和notify的范常式序。在這個程序里,我們使用了上文所述的一些代碼規范。我們有兩個線程,分別名為
PRODUCER(生產者)和CONSUMER(消費者),他們分別繼承了了Procer和Consumer類,而Procer和
Consumer都繼承了Thread類。Procer和Consumer想要實現的代碼邏輯都在run()函數內。Main線程開始了生產者和消費
者線程,並聲明了一個LinkedList作為緩沖區隊列(在Java中,LinkedList實現了隊列的介面)。生產者在無限循環中持續往
LinkedList里插入隨機整數直到LinkedList滿。我們在while(queue.size ==
maxSize)循環語句中檢查這個條件。請注意到我們在做這個檢查條件之前已經在隊列對象上使用了synchronized關鍵詞,因而其它線程不能在
我們檢查條件時改變這個隊列。如果隊列滿了,那麼PRODUCER線程會在CONSUMER線程消耗掉隊列里的任意一個整數,並用notify來通知
PRODUCER線程之前持續等待。在我們的例子中,wait和notify都是使用在同一個共享對象上的。
import java.util.LinkedList; import java.util.Queue; import java.util.Random; /** * Simple Java program to demonstrate How to use wait, notify and notifyAll() * method in Java by solving procer consumer problem. * * @author Javin Paul */ public class ProcerConsumerInJava { public static void main(String args[]) { System.out.println("How to use wait and notify method in Java"); System.out.println("Solving Procer Consumper Problem"); Queue<Integer> buffer = new LinkedList<>(); int maxSize = 10; Thread procer = new Procer(buffer, maxSize, "PRODUCER"); Thread consumer = new Consumer(buffer, maxSize, "CONSUMER"); procer.start(); consumer.start(); } } /** * Procer Thread will keep procing values for Consumer * to consumer. It will use wait() method when Queue is full * and use notify() method to send notification to Consumer * Thread. * * @author WINDOWS 8 * */ class Procer extends Thread { private Queue<Integer> queue; private int maxSize; public Procer(Queue<Integer> queue, int maxSize, String name){ super(name); this.queue = queue; this.maxSize = maxSize; } @Override public void run() { while (true) { synchronized (queue) { while (queue.size() == maxSize) { try { System.out .println("Queue is full, " + "Procer thread waiting for " + "consumer to take something from queue"); queue.wait(); } catch (Exception ex) { ex.printStackTrace(); } } Random random = new Random(); int i = random.nextInt(); System.out.println("Procing value : " + i); queue.add(i); queue.notifyAll(); } } } } /** * Consumer Thread will consumer values form shared queue. * It will also use wait() method to wait if queue is * empty. It will also use notify method to send * notification to procer thread after consuming values * from queue. * * @author WINDOWS 8 * */ class Consumer extends Thread { private Queue<Integer> queue; private int maxSize; public Consumer(Queue<Integer> queue, int maxSize, String name){ super(name); this.queue = queue; this.maxSize = maxSize; } @Override public void run() { while (true) { synchronized (queue) { while (queue.isEmpty()) { System.out.println("Queue is empty," + "Consumer thread is waiting" + " for procer thread to put something in queue"); try { queue.wait(); } catch (Exception ex) { ex.printStackTrace(); } } System.out.println("Consuming value : " + queue.remove()); queue.notifyAll(); } } } }

為了更好地理解這個程序,我建議你在debug模式里跑這個程序。一旦你在debug模式下啟動程序,它會停止在PRODUCER或者
CONSUMER線程上,取決於哪個線程占據了CPU。因為兩個線程都有wait()的條件,它們一定會停止,然後你就可以跑這個程序然後看發生什麼了
(很有可能它就會輸出我們以上展示的內容)。你也可以使用Eclipse里的Step into和Step over按鈕來更好地理解多線程間發生的事情。

本文重點:

1. 你可以使用wait和notify函數來實現線程間通信。你可以用它們來實現多線程(>3)之間的通信。

2. 永遠在synchronized的函數或對象里使用wait、notify和notifyAll,不然Java虛擬機會生成 IllegalMonitorStateException。

3. 永遠在while循環里而不是if語句下使用wait。這樣,循環會在線程睡眠前後都檢查wait的條件,並在條件實際上並未改變的情況下處理喚醒通知。

4. 永遠在多線程間共享的對象(在生產者消費者模型里即緩沖區隊列)上使用wait。

5. 基於前文提及的理由,更傾向用 notifyAll(),而不是 notify()。

這是關於Java里如何使用wait,
notify和notifyAll的所有重點啦。你應該只在你知道自己要做什麼的情況下使用這些函數,不然Java里還有很多其它的用來解決同步問題的方

案。例如,如果你想使用生產者消費者模型的話,你也可以使用BlockingQueue,它會幫你處理所有的線程安全問題和流程式控制制。如果你想要某一個線

程等待另一個線程做出反饋再繼續運行,你也可以使用CycliBarrier或者CountDownLatch。如果你只是想保護某一個資源的話,你也可
以使用Semaphore。

『肆』 如何在 Java 中正確使用 wait,notify 和 notifyAll

我們先來了解一下為什麼要使用wait,notify


首先看一下以下代碼:

synchronized(a){
...//1
synchronized(b){
}
}
synchronized(b){
...//2
synchronized(a){
}
}

假設現在有兩個線程, t1 線程運行到了//1 的位置,而 t2 線程運行到了//2 的位置,接

下來會發生什麼情況呢?

此時, a 對象的鎖標記被 t1 線程獲得,而 b 對象的鎖標記被 t2 線程獲得。對於 t1 線程

而言,為了進入對 b 加鎖的同步代碼塊, t1 線程必須獲得 b 對象的鎖標記。由於 b 對象的鎖標記被 t2 線程獲得, t1 線程無法獲得這個對象的鎖標記,因此它會進入 b 對象的鎖池,等待 b 對象鎖標記的釋放。而對於 t2 線程而言,由於要進入對 a 加鎖的同步代碼塊,由於 a 對象的鎖標記在 t1 線程手中,因此 t2 線程會進入 a 對象的鎖池。

此時, t1 線程在等待 b 對象鎖標記的釋放,而 t2 線程在等待 a 對象鎖標記的釋放。由

於兩邊都無法獲得所需的鎖標記,因此兩個線程都無法運行。這就是「死鎖」問題。


在 Java 中,採用了 wait 和 notify 這兩個方法,來解決死鎖機制。

首先,在 Java 中,每一個對象都有兩個方法: wait 和 notify 方法。這兩個方法是定義

在 Object 類中的方法。對某個對象調用 wait()方法,表明讓線程暫時釋放該對象的鎖標記。

例如,上面的代碼就可以改成:

synchronized(a){
...//1
a.wait();
synchronized(b){
}
}
synchronized(b){
...//2
synchronized(a){
...
a.notify();
}
}

這樣的代碼改完之後,在//1 後面, t1 線程就會調用 a 對象的 wait 方法。此時, t1 線程

會暫時釋放自己擁有的 a 對象的鎖標記,而進入另外一個狀態:等待狀態。

要注意的是,如果要調用一個對象的 wait 方法,前提是線程已經獲得這個對象的鎖標

記。如果在沒有獲得對象鎖標記的情況下調用 wait 方法,則會產生異常。

由於 a 對象的鎖標記被釋放,因此, t2 對象可以獲得 a 對象的鎖標記,從而進入對 a

加鎖的同步代碼塊。在同步代碼塊的最後,調用 a.notify()方法。這個方法與 wait 方法相對應,是讓一個線程從等待狀態被喚醒。

那麼 t2 線程喚醒 t1 線程之後, t1 線程處於什麼狀態呢?由於 t1 線程喚醒之後還要在

對 a 加鎖的同步代碼塊中運行,而 t2 線程調用了 notify()方法之後,並沒有立刻退出對 a 鎖的同步代碼塊,因此此時 t1 線程並不能馬上獲得 a 對象的鎖標記。因此,此時, t1 線程會在 a 對象的鎖池中進行等待,以期待獲得 a 對象的鎖標記。也就是說,一個線程如果之前調用了 wait 方法,則必須要被另一個線程調用 notify()方法喚醒。喚醒之後,會進入鎖池狀態。線程狀態轉換圖如下:

classConsumerextendsThread{
privateMyStackms;
publicConsumer(MyStackms){
this.ms=ms;
}
publicvoidrun(){
while(true){
//為了保證push和pop操作的完整性
//必須加synchronized
synchronized(ms){
//如果棧空間已滿,則wait()釋放ms的鎖標記
while(ms.isEmpty()){
try{
ms.wait();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
charch=ms.pop();
System.out.println("Pop"+ch);
ms.notifyAll();
}
//push之後隨機休眠一段時間
try{
sleep((int)Math.abs(Math.random()*100));
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
}
//生產者
classProcerextendsThread{
privateMyStackms;
publicProcer(MyStackms){
this.ms=ms;
}
publicvoidrun(){
while(true){
//為了保證push和pop操作的完整性
//必須加synchronized
synchronized(ms){
//如果棧空間已滿,則wait()釋放ms的鎖標記
while(ms.isFull()){
try{
ms.wait();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
ms.push('A');
System.out.println("pushA");
ms.notifyAll();
}
//push之後隨機休眠一段時間
try{
sleep((int)Math.abs(Math.random()*200));
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
}
//主方法中,啟用生產者與消費者兩個線程
publicclassTestWaitNotify{
publicstaticvoidmain(String[]args){
MyStackms=newMyStack();
Threadt1=newProcer(ms);
Threadt2=newConsumer(ms);
t1.start();
t2.start();
}
}

部分代碼純手打,望採納~

『伍』 java調用python腳本

java調用python腳本是怎樣的呢?下面就讓我們一起來了解一下吧:
在日常生活中比較常見的java調用python腳本方法有兩種,即:
1、通過Jython.jar提供的類庫實現。
2、通過Runtime.getRuntime()開啟進程來執行腳本文件。
不過第二種方法可能會更好一些,因為Python有時候也是需要用到第三方庫的,例如requests,而Python並不支持。因此本地安裝Python環境時需要再安裝第三方庫,然後使用Java調用即可。
參考範例:
Python代碼示例:
def hello():
print(Hello,Python)
if __name__ == __main__:
hello()
Java代碼示例:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class HelloPython {
public static void main(String[] args) {
String[] arguments = new String[] {python, E://workspace/hello.py};
try {
Process process = Runtime.getRuntime().exec(arguments);
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream(),
GBK));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
//java代碼中的process.waitFor()返回值為0表示調用python腳本成功,
//返回值為1表示調用python腳本失敗,這和通常意義上見到的0與1定義正好是相反的
int re = process.waitFor();
System.out.println(re);
} catch (Exception e) {
e.printStackTrace();
}
}
}

『陸』 Java簡歷中工作經驗怎麼寫

錯誤示範:

1、java後台開發

2、前端編寫

正確範例:

1、java程序開發崗位,主要負責:代碼編寫、資料庫操作、sql語句優化、wsdl技術調用介面、生成介面等。

2、本身掌握的前端技術加上工作期間積累的html5和css3知識,會同時負責前端的實現。

3、git項目管理,包括:遠程git倉庫項目的創建與刪除等、gitolite中項目操作許可權的設置等。

4、研究並使用大數據相關的技術用於解決海量日誌的分析,將數據存儲到hadoop平台,然後將分析結果導入到Oracle資料庫,通過Spring框架將結果進行展示。

閱讀全文

與java程序開發範例相關的資料

熱點內容
愛奇藝上海演算法團隊 瀏覽:138
程序員顏值高的人 瀏覽:362
西數硬體加密和閃迪軟體加密 瀏覽:716
聲控足球解壓黏土教程 瀏覽:639
linux下的嵌入式開發 瀏覽:173
電腦3d加速命令 瀏覽:105
加密手機號碼是怎麼回事 瀏覽:921
女程序員真實圖片 瀏覽:696
pic單片機燒寫 瀏覽:814
linuxping結果 瀏覽:196
單片機採集負電壓 瀏覽:407
伺服器收件什麼意思 瀏覽:893
單片機發數組 瀏覽:884
魔方虛擬主機銷售系統源碼 瀏覽:709
rsa驗簽php源碼 瀏覽:514
github怎麼直接打開源碼 瀏覽:529
和家親app怎麼下載不了了 瀏覽:728
藍屏程序員 瀏覽:78
androidinflatexml 瀏覽:489
魔獸爭霸2下載好了怎麼解壓 瀏覽:920