java timer 线程安全_多线程之 线程安全与控制
線程控制
wait和notify方法需要注意的細(xì)節(jié):wait方法與notify方法必須要由同一個(gè)鎖對(duì)象調(diào)用。因?yàn)?#xff1a;對(duì)應(yīng)的鎖對(duì)象可以通過(guò)notify喚醒使用同一個(gè)鎖對(duì) 象調(diào)用的wait方法后的線程。
wait方法與notify方法是屬于Object類的方法的。因?yàn)?#xff1a;鎖對(duì)象可以是任意對(duì)象,而任意對(duì)象的所屬類都是繼 承了Object類的。
wait方法與notify方法必須要在同步代碼塊或者是同步函數(shù)中使用。因?yàn)?#xff1a;必須要通過(guò)鎖對(duì)象調(diào)用這2個(gè)方 法。
休眠線程:Thread.sleep(毫秒) 秒 毫秒 微秒 納秒 進(jìn)制1000 時(shí)間到了自動(dòng)喚醒線程
守護(hù)線程:線程對(duì)象.setDaemon(Boolean)。設(shè)置該線程對(duì)象為守護(hù)線程,該線程一旦停止,其他線程開(kāi)始自殺。
加入線程:對(duì)象.join():該線程立即插隊(duì),直到該線程都結(jié)束才能繼續(xù)執(zhí)行。 對(duì)象.join(毫秒) :該線程立即執(zhí)行n毫秒之后再和其他線程正常搶奪CPU資源。
禮讓線程:Thread.yield():表示當(dāng)前線程對(duì)象提示調(diào)度器自己愿意讓出CPU資源,但是調(diào)度器可以自由忽略
設(shè)置線程優(yōu)先級(jí):
對(duì)象.setPriority(1):最低級(jí) 對(duì)象.setPriority(5):默認(rèn)級(jí) 對(duì)象.setPriority(10):最高級(jí)
線程安全問(wèn)題:1)靜態(tài) = 共享 2)如果以引用數(shù)據(jù)類型成員變量當(dāng)做鎖對(duì)象,必須用靜態(tài)的 3)多次啟動(dòng)一個(gè)線程定是非法的
死鎖:多線程同步的時(shí)候,如果同步代碼嵌套,使用相同鎖,就有可能出現(xiàn)死鎖,就是相互爭(zhēng)奪鑰匙的時(shí)候
回顧線程安全類:安全 Vector、StringBuffer、HashTable
不安全 ArrayList、StringBuilder、HashMap
進(jìn)一步認(rèn)識(shí)線程
1.Runtime類exec(“命令”) 結(jié)果等于在cmd里敲命令
2.Timer()類指定任務(wù)在指定時(shí)間執(zhí)行或重復(fù)
3.兩個(gè)線程之間的通信1)線程等待:鎖對(duì)象.wait(); 2)線程喚醒:鎖對(duì)象.notify();
4.三個(gè)及以上線程之間的通信
本線程要關(guān)閉 其他線程要開(kāi)啟。
5.互斥鎖ReenTrantLock; lock()獲取鎖 unLock()釋放鎖 newCondition()獲取Condition對(duì)象; Condition;await等待 signal 喚醒
6.線程組的概述和使用Java中使用GrepThread來(lái)表示線程組,它可以對(duì)一批線程進(jìn)行分類管理,Java允許程序直接對(duì)線程組進(jìn)行控制。 默認(rèn)情況下,所有線程屬于線程組。 getThreadGroup 通過(guò)線程對(duì)象獲取所在的組 getName通過(guò)線程對(duì)象獲取所在的組的名字 也可以給線程設(shè)置分組。 創(chuàng)建一個(gè)線程組并賦予名字ThreadGroup(name); 創(chuàng)建線程對(duì)象 Thread(ThreadGroup ? group, Runnable?target,String?name) 設(shè)置整組的優(yōu)先級(jí)或者守護(hù)線程。
案例演示
public class 線程組 {
public static void main(String[] args) {
MyRunnable ticket = new MyRunnable();
ThreadGroup join = new ThreadGroup("join");
//開(kāi)發(fā)中沒(méi)見(jiàn)到過(guò) 用到的時(shí)候再看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 }
}
線程組的使用,默認(rèn)是主線程組。
2.7線程的5種狀態(tài)NEW(新建)-----------------線程剛被創(chuàng)建,但是并未啟動(dòng)。還沒(méi)調(diào)用start方法。 Runnable(可運(yùn)行)----------線程可以在java虛擬機(jī)中運(yùn)行的狀態(tài),可能正在運(yùn)行自己代碼,也可能沒(méi)有,這取決于操 作系統(tǒng)處理器。 Blocked(鎖阻塞)-----------當(dāng)一個(gè)線程試圖獲取一個(gè)對(duì)象鎖,而該對(duì)象鎖被其他的線程持有,則該線程進(jìn)入Blocked狀 態(tài);當(dāng)該線程持有鎖時(shí),該線程將變成Runnable狀態(tài)。 Waiting(無(wú)限等待)---------一個(gè)線程在等待另一個(gè)線程執(zhí)行一個(gè)(喚醒)動(dòng)作時(shí),該線程進(jìn)入Waiting狀態(tài)。進(jìn)入這個(gè) 狀態(tài)后是不能自動(dòng)喚醒的,必須等待另一個(gè)線程調(diào)用notify或者notifyAll方法才能夠喚醒。 Timed Waiting(計(jì)時(shí)等待)---同waiting狀態(tài),有幾個(gè)方法有超時(shí)參數(shù),調(diào)用他們將進(jìn)入Timed Waiting狀態(tài)。這一狀態(tài) 將一直保持到超時(shí)期滿或者接收到喚醒通知。帶有超時(shí)參數(shù)的常用方法有Thread.sleep 、 Object.wait。 Teminated(被終止)---------因?yàn)閞un方法正常退出而死亡,或者因?yàn)闆](méi)有捕獲的異常終止了run方法而死亡。
線程安全
同步代碼塊&鎖:
什么情況下需要同步代碼塊1.當(dāng)多線程并發(fā),有多段代碼同時(shí)執(zhí)行時(shí),我們希望某一段代碼執(zhí)行的過(guò)程中CPU不要切換到其他線程工作,這時(shí)就需要同步。 2.如果兩段代碼是同步的,那么同一時(shí)間只能執(zhí)行一段,在一段代碼執(zhí)行結(jié)束之前,不會(huì)執(zhí)行另一段代碼。
同步代碼塊1.使用synchronize關(guān)鍵字加上一個(gè)鎖對(duì)象來(lái)定義一段代碼,這就叫同步代碼塊 2.多個(gè)代碼塊使用同一個(gè)多對(duì)象,那么他們就是同步的
同時(shí)滿足以下三點(diǎn)會(huì)出現(xiàn)不安全的問(wèn)題1.多線程環(huán)境 2.有共享數(shù)據(jù) 3.多條語(yǔ)句操作共享數(shù)據(jù)
如何解決破壞以上一條
實(shí)現(xiàn)用代碼塊包裹操作共享數(shù)據(jù)的代碼
演示
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){ 上面 】 犯了大錯(cuò)了 浪費(fèi)時(shí)間 while (ticket>0){
try {
System.out.println("出票編號(hào):"+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.在成員變量的位置創(chuàng)建一個(gè)ReentrantLock對(duì)象* 2.在可能出現(xiàn)問(wèn)題的代碼前使用lock()獲取鎖;* 3.在可能出現(xiàn)問(wèn)題的代碼后使用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("出票編號(hào):"+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();
}
}
結(jié)論1:非static同步函數(shù)鎖的名字是類名.class = this 2:static靜態(tài)沒(méi)有this ,而是該類的.Class對(duì)象 = 字節(jié)碼對(duì)象 3:方法鎖 的對(duì)象是this 4: 可以使用任意對(duì)象做鎖對(duì)象,但是不能使用匿名對(duì)象,同步鎖的對(duì)象要是同一 個(gè)對(duì)象。
總結(jié)
以上是生活随笔為你收集整理的java timer 线程安全_多线程之 线程安全与控制的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java isinterrupted_J
- 下一篇: java z+_Java Z 字形变换