?? thread.txt
字號:
public Product(int productID,String productName)
{
this.productID=productID;
this.productName=productName;
}
public String toString()
{
StringBuffer sb=new StringBuffer();
sb.append("{");
sb.appentd("productID="+this.productID+";");
sp.append("productName="+this.productName+";");
sb.append("}");
return sb.toString();
}
}
public class WareHouse
{
private int maxSize;
private int size;
private int front=0;
private int vear=-1;
private Product products[];
public WareHouse(int maxSize)
{
this.maxSize=maxSize;
this.size=0;
products=new Product[this.maxSize];
}
public synchronized void add(Product product)
{
//只有Producer才可以生產(chǎn)產(chǎn)品
Thread temp=Thread.currendThead();
if(temp.getClass.equals(Producer.class))
{
Producer producer=(Producer)temp;
while(this.isFull() && producer.isRunning)
{
System.out.println(producer.getName()+"要等待");
wait;
System.out.println(producer.getName()+"激活了");
}
this.products[++vear]=product;
if(vear==this.maxSize-1)
{
vear=-1;
}
}
}
public synchronized Product remove()
{
if(this.isEmpty())
{
wait;
}
Product temp=this.products[front++];
if(front==this.maxSize)
{
front=0;
}
return temp;
}
public boolean isFull()
{
retrurn this.siz==maxSize;
}
public boolean isEmpty()
{
return this.size==0;
}
}
public class Producer extends Thread
{
private WareHouse wareHouse;
private boolean isRunning=true;
private static int i;
public Producer(String threadName,WareHouse wareHouse)
{
super(threadName);
this.wareHouse=wareHouse;
}
public void run()
{
while(isRunning)
{
i++;
Product product=new Product(i,"name"+i);
wareHouse.add(product);
Thread.sleep(1000);
}
}
public void stopProducer()
{
synchronized(wareHouse)
{
this.isRunning=false;
//在關(guān)閉前激活一下所有的線程
notifyAll();
}
}
}
public class Consumer extends Thread
{
public void run()
{
}
}
三、join:讓主線程等待所有的子線程執(zhí)行完后再執(zhí)行。
四、setDaemon:在線程start之前設(shè)置,將當(dāng)前線程設(shè)置為守護(hù)線程,
當(dāng)其它線程結(jié)束后,守護(hù)線程自動停止。
守護(hù)線程為其它線程提供服務(wù)。
五、setPriority:設(shè)置線程運(yùn)行的優(yōu)先級,默認(rèn)是5,優(yōu)先級越高越提前
執(zhí)行。
六、取出虛擬機(jī)下的所有線程
線程組:ThreadGroup,一個線程組可以有多個線程,也可以有很多子線程組
線程:Thread
實(shí)例化線程:
new Thread(Runnable run);
new Thread(Runnable run,String ThreadName);
new Thread(String ThreadName);
//基于runnable實(shí)現(xiàn)一個線程,ThreadName是線程的名稱,ThreadGroup代表當(dāng)前線程屬于那一個線程組
new Thread(ThreadGroup tg,Runnable run,String ThreadName);
new Thread(ThreadGroup tg,String ThreadName)
實(shí)例化線程組:
//當(dāng)前的線程組從屬于那一個線程組
new ThreadGroup(ThreadGroup tg,String ThreadName);
new ThreadGroup(String ThreadName)
方法:
currentThread():得到調(diào)用當(dāng)對象的線程
enumerate(Thread[] tarray): 將當(dāng)前線程的線程組及其子組中的每一個活動線程引用復(fù)制到指定的數(shù)組中。
enumerate(Thread[] tarray,false): 當(dāng)前線程組內(nèi)的每一個活動線程引用復(fù)制到數(shù)組中。
enumerate(ThreadGroup[] tarray): 將當(dāng)前線程的線程組及其子組中的每一個活動線程引用復(fù)制到指定的數(shù)組中。
enumerate(ThreadGroup[] tarray,false): 當(dāng)前線程組內(nèi)的每一個活動線程組的引用復(fù)制到數(shù)組中。
getThreadGroup();返回該線程所屬的線程組。
void interrupt(): 中斷線程。
static boolean interrupted(): 測試當(dāng)前線程是否已經(jīng)中斷。
boolean isAlive(): 測試線程是否處于活動狀態(tài)。
boolean isDaemon():測試該線程是否為守護(hù)線程。
boolean isInterrupted():測試線程是否已經(jīng)中斷。
void join():等待該線程終止。
setPriority(int newPriority) :線程的優(yōu)先級。
yield():暫停當(dāng)前正在執(zhí)行的線程對象,釋放資源,并執(zhí)行其他線程,將其放到線程隊(duì)列的最后。
activeCount() :返回當(dāng)前線程的線程組中活動線程的數(shù)目。
七、產(chǎn)生一個線程是很浪費(fèi)時間的,如果事選將多個線程放到線程池中,
有任務(wù)時取出一個線程,沒有任務(wù)時線程處于等待狀態(tài)。
線程池:
1、有線程數(shù)組,存放活動線程
2、有一個任務(wù)列表,存放任務(wù),將任務(wù)依次取出
一、死鎖:一個線程占用一個資源,又想得到另一個線程占用的資源,只能等待。
另一個線程占用一個資源,又想得到前一個線程占用的資源,也只能等待。
這樣兩個線程出現(xiàn)死鎖。
public class MyThread1 extends Thread
{
private Object resource1;
private Object resource2;
public MyThread1(Object resource1,Object resource2)
{
this.resource1=resource1;
this.resource2=resource2;
}
public void run()
{
synchronized(resource1)
{
System.out.println("正在執(zhí)行資源1號");
Thread.sleep(50);
synchronized(resource2)
{
System.out.println("正在執(zhí)行資源2號");
}
}
}
}
public class MyThread2 extends Thread
{
private Object resource1;
private Object resource2;
public MyThread2(Object resource1,Object resource2)
{
this.resource1=resource1;
this.resource2=resource2;
}
public void run()
{
synchronized(resource2)
{
System.out.println("正在執(zhí)行資源2號");
Thread.sleep(50);
synchronized(resource1)
{
System.out.println("正在執(zhí)行資源1號");
}
}
}
}
二、Timer過一段時間執(zhí)行一個線程或某一時間點(diǎn)執(zhí)行一個線程
或隔多長時間執(zhí)行一個線程。
1、實(shí)現(xiàn)執(zhí)行任務(wù)的線程,必須繼承于TimerTask
public class MyThread extends TimerTask
{
public void run()
{
}
}
2、通過Timer類調(diào)用
Timer timer=new Timer();
MyThread mt=new MyThread();
timer.schedule(mt,1000);//1秒后運(yùn)行線程mt
timer.schedule(mt,1000,1000);//1秒后運(yùn)行線程mt,同時每隔1秒后執(zhí)行mt
timer.schedule(mt,date);//某個時間點(diǎn)執(zhí)行mt
timer.cancel();//代表退出
四、線程的作用
進(jìn)程內(nèi)的并發(fā)
五、線程與進(jìn)程的區(qū)別
共同點(diǎn):
都是并發(fā)
不同點(diǎn):
進(jìn)程有獨(dú)立的內(nèi)存空間,線程沒有獨(dú)立內(nèi)存空間。
進(jìn)程間的通信耗費(fèi)較大的資源,線程間的通信比較容易。
進(jìn)程的并發(fā)是由線程實(shí)現(xiàn)的。
六、線程實(shí)現(xiàn)
1、繼承于Thread類,覆蓋run()方法,通過start啟動線程,調(diào)用run方法。
2、實(shí)現(xiàn)Runnable接口,實(shí)現(xiàn)run()方法。實(shí)例化該類,通過構(gòu)造子將其傳到一個Thread對象中
,通過start啟動線程,調(diào)用run方法
七、線程的同步
--臟讀:后一個事務(wù)用了前一個事務(wù)沒有確認(rèn)的數(shù)據(jù)
事務(wù)1
update buy set amount=amount+100 where buyID=1;
rollback;
事務(wù)2:在事務(wù)1修改但沒有執(zhí)行rollback前,執(zhí)行當(dāng)前update交提交
update buy set amount=amount+100 where buyID=1;
commit;
--覆蓋更新:后一個事務(wù)將前一個事務(wù)的更新覆蓋了。
(update一讀到就加鎖)兩個事務(wù)同時讀取,因?yàn)槭聞?wù)1所在主機(jī)速度快先更新并提交,
然后事務(wù)2更新并提交。
事務(wù)1
update buy set amount=amount+100 where buyID=1;
commit;
事務(wù)2:
update buy set amount=amount+100 where buyID=1;
commit;
臟讀就是指當(dāng)一個事務(wù)正在訪問數(shù)據(jù),并且對數(shù)據(jù)進(jìn)行了修改,而這種修改還沒有提交到數(shù)據(jù)庫中,這時,另外一個事務(wù)也訪問這個數(shù)據(jù),然后使用了這個數(shù)據(jù)。因?yàn)檫@個數(shù)據(jù)是還沒有提交的數(shù)據(jù),那么另外一個事務(wù)讀到的這個數(shù)據(jù)是臟數(shù)據(jù),依據(jù)臟數(shù)據(jù)所做的操作可能是不正確的。不可重復(fù)讀是指在一個事務(wù)內(nèi),多次讀同一數(shù)據(jù)。在這個事務(wù)還沒有結(jié)束時,另外一個事務(wù)也訪問該同一數(shù)據(jù)。那么,在第一個事務(wù)中的兩次讀數(shù)據(jù)之間,由于第二個事務(wù)的修改,那么第一個事務(wù)兩次讀到的的數(shù)據(jù)可能是不一樣的。這樣就發(fā)生了在一個事務(wù)內(nèi)兩次讀到的數(shù)據(jù)是不一樣的,因此稱為是不可重復(fù)讀。幻覺讀是指當(dāng)事務(wù)不是獨(dú)立執(zhí)行時發(fā)生的一種現(xiàn)象,例如第一個事務(wù)對一個表中的數(shù)據(jù)進(jìn)行了修改,這種修改涉及到表中的全部數(shù)據(jù)行。同時,第二個事務(wù)也修改這個表中的數(shù)據(jù),這種修改是向表中插入一行新數(shù)據(jù)。那么,以后就會發(fā)生操作第一個事務(wù)的用戶發(fā)現(xiàn)表中還有沒有修改的數(shù)據(jù)行,就好象發(fā)生了幻覺一樣。
什么是線程同步:一個對象的一個同步方法被一個線程調(diào)用,另一個線程不管調(diào)用當(dāng)前同步方法
還是其它的同步方法只能等待同步方法執(zhí)行結(jié)束,調(diào)用非同步方法不影響。
實(shí)現(xiàn)方法:
public synchronized void a1()
{
}
在線程的run方法中說明是一個同步對象,調(diào)用這個對象的所有方法都是同步方法。
synchronized(co)
{
co.test1();
}
通訊的兩種方式:
1、基于tcp/ip協(xié)議,用Sockect實(shí)現(xiàn)
特點(diǎn):產(chǎn)生會話,穩(wěn)定,每一次交互都有確認(rèn)。
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -