java timer 线程安全_多线程之 线程安全与控制
線程控制
wait和notify方法需要注意的細節:wait方法與notify方法必須要由同一個鎖對象調用。因為:對應的鎖對象可以通過notify喚醒使用同一個鎖對 象調用的wait方法后的線程。
wait方法與notify方法是屬于Object類的方法的。因為:鎖對象可以是任意對象,而任意對象的所屬類都是繼 承了Object類的。
wait方法與notify方法必須要在同步代碼塊或者是同步函數中使用。因為:必須要通過鎖對象調用這2個方 法。
休眠線程:Thread.sleep(毫秒) 秒 毫秒 微秒 納秒 進制1000 時間到了自動喚醒線程
守護線程:線程對象.setDaemon(Boolean)。設置該線程對象為守護線程,該線程一旦停止,其他線程開始自殺。
加入線程:對象.join():該線程立即插隊,直到該線程都結束才能繼續執行。 對象.join(毫秒) :該線程立即執行n毫秒之后再和其他線程正常搶奪CPU資源。
禮讓線程:Thread.yield():表示當前線程對象提示調度器自己愿意讓出CPU資源,但是調度器可以自由忽略
設置線程優先級:
對象.setPriority(1):最低級 對象.setPriority(5):默認級 對象.setPriority(10):最高級
線程安全問題:1)靜態 = 共享 2)如果以引用數據類型成員變量當做鎖對象,必須用靜態的 3)多次啟動一個線程定是非法的
死鎖:多線程同步的時候,如果同步代碼嵌套,使用相同鎖,就有可能出現死鎖,就是相互爭奪鑰匙的時候
回顧線程安全類:安全 Vector、StringBuffer、HashTable
不安全 ArrayList、StringBuilder、HashMap
進一步認識線程
1.Runtime類exec(“命令”) 結果等于在cmd里敲命令
2.Timer()類指定任務在指定時間執行或重復
3.兩個線程之間的通信1)線程等待:鎖對象.wait(); 2)線程喚醒:鎖對象.notify();
4.三個及以上線程之間的通信
本線程要關閉 其他線程要開啟。
5.互斥鎖ReenTrantLock; lock()獲取鎖 unLock()釋放鎖 newCondition()獲取Condition對象; Condition;await等待 signal 喚醒
6.線程組的概述和使用Java中使用GrepThread來表示線程組,它可以對一批線程進行分類管理,Java允許程序直接對線程組進行控制。 默認情況下,所有線程屬于線程組。 getThreadGroup 通過線程對象獲取所在的組 getName通過線程對象獲取所在的組的名字 也可以給線程設置分組。 創建一個線程組并賦予名字ThreadGroup(name); 創建線程對象 Thread(ThreadGroup ? group, Runnable?target,String?name) 設置整組的優先級或者守護線程。
案例演示
public class 線程組 {
public static void main(String[] args) {
MyRunnable ticket = new MyRunnable();
ThreadGroup join = new ThreadGroup("join");
//開發中沒見到過 用到的時候再看API Thread windows_1 = new Thread(join, ticket, "windows_1");
Thread windows_2 = new Thread(join,ticket,"windows_2");
Thread windows_3 = new Thread(ticket,"windows_2");
String name1 = windows_1.getThreadGroup().getName();
String name2 = windows_2.getThreadGroup().getName();
String name3 = windows_3.getThreadGroup().getName(); System.out.println(name1.equals(name2)+" "+name1);//true join System.out.println(name1.equals(name3)+" "+name2);//false join System.out.println(name2.equals(name3)+" "+name3);//false main }
}
線程組的使用,默認是主線程組。
2.7線程的5種狀態NEW(新建)-----------------線程剛被創建,但是并未啟動。還沒調用start方法。 Runnable(可運行)----------線程可以在java虛擬機中運行的狀態,可能正在運行自己代碼,也可能沒有,這取決于操 作系統處理器。 Blocked(鎖阻塞)-----------當一個線程試圖獲取一個對象鎖,而該對象鎖被其他的線程持有,則該線程進入Blocked狀 態;當該線程持有鎖時,該線程將變成Runnable狀態。 Waiting(無限等待)---------一個線程在等待另一個線程執行一個(喚醒)動作時,該線程進入Waiting狀態。進入這個 狀態后是不能自動喚醒的,必須等待另一個線程調用notify或者notifyAll方法才能夠喚醒。 Timed Waiting(計時等待)---同waiting狀態,有幾個方法有超時參數,調用他們將進入Timed Waiting狀態。這一狀態 將一直保持到超時期滿或者接收到喚醒通知。帶有超時參數的常用方法有Thread.sleep 、 Object.wait。 Teminated(被終止)---------因為run方法正常退出而死亡,或者因為沒有捕獲的異常終止了run方法而死亡。
線程安全
同步代碼塊&鎖:
什么情況下需要同步代碼塊1.當多線程并發,有多段代碼同時執行時,我們希望某一段代碼執行的過程中CPU不要切換到其他線程工作,這時就需要同步。 2.如果兩段代碼是同步的,那么同一時間只能執行一段,在一段代碼執行結束之前,不會執行另一段代碼。
同步代碼塊1.使用synchronize關鍵字加上一個鎖對象來定義一段代碼,這就叫同步代碼塊 2.多個代碼塊使用同一個多對象,那么他們就是同步的
同時滿足以下三點會出現不安全的問題1.多線程環境 2.有共享數據 3.多條語句操作共享數據
如何解決破壞以上一條
實現用代碼塊包裹操作共享數據的代碼
演示
public class 多線程安全 {
public static void main(String[] args) {
MyRunnable ticket = new MyRunnable();
Thread windows_1 = new Thread(ticket,"windows_1");
Thread windows_2 = new Thread(ticket,"windows_2");
Thread windows_3 = new Thread(ticket,"windows_3");
Thread windows_4 = new Thread(ticket,"windows_3");
windows_1.setPriority(9);
windows_2.setPriority(8);
windows_3.setPriority(7);
windows_4.setPriority(6);
windows_1.start();
windows_2.start();
windows_3.start();
windows_4.start();
}
}
class MyRunnable implements Runnable{
private static int ticket = 100;
private Object obj = new Object();
@Override
public void run() {
synchronized (obj){
// 【synchronized (obj){】這一行 一定要在 【while (ticket>0){ 上面 】 犯了大錯了 浪費時間 while (ticket>0){
try {
System.out.println("出票編號:"+ticket+"\t"+
" 剩余票:" + --ticket +"\t"+
Thread.currentThread().getName()+"\t"+
new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date(System.currentTimeMillis())));
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Lock
/*** 1.在成員變量的位置創建一個ReentrantLock對象* 2.在可能出現問題的代碼前使用lock()獲取鎖;* 3.在可能出現問題的代碼后使用unlock()釋放鎖;*/
class MyRunnable implements Runnable{
private static int ticket = 100;
private Lock lock = new ReentrantLock();
@Override
public void run() {
lock.lock();
while (ticket>0){
try {
System.out.println("出票編號:"+ticket+"\t"+
" 剩余票:" + --ticket +"\t"+
Thread.currentThread().getName()+"\t"+
new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date(System.currentTimeMillis())));
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.unlock();
}
}
class LockTest {
public static void main(String[] args) {
MyRunnable ticket = new MyRunnable();
Thread windows_1 = new Thread(ticket,"windows_1");
Thread windows_2 = new Thread(ticket,"windows_2");
Thread windows_3 = new Thread(ticket,"windows_3");
windows_1.setPriority(9);
windows_2.setPriority(8);
windows_3.setPriority(7);
windows_1.start();
windows_2.start();
windows_3.start();
}
}
結論1:非static同步函數鎖的名字是類名.class = this 2:static靜態沒有this ,而是該類的.Class對象 = 字節碼對象 3:方法鎖 的對象是this 4: 可以使用任意對象做鎖對象,但是不能使用匿名對象,同步鎖的對象要是同一 個對象。
總結
以上是生活随笔為你收集整理的java timer 线程安全_多线程之 线程安全与控制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java isinterrupted_J
- 下一篇: 几天后自动领取java怎么做的_java