方法1:用mysql命令鎖住表.
成都創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、網(wǎng)站制作、大渡口網(wǎng)絡(luò)推廣、成都微信小程序、大渡口網(wǎng)絡(luò)營銷、大渡口企業(yè)策劃、大渡口品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;成都創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供大渡口建站搭建服務(wù),24小時服務(wù)熱線:18982081108,官方網(wǎng)址:www.cdcxhl.com
public?void?test()?{??
String?sql?=?"lock?tables?aa1?write";??
//?或String?sql?=?"lock?tables?aa1?read";???
//?如果想鎖多個表?lock?tables?aa1?read?,aa2?write?,?.....???
String?sql1?=?"select?*?from?aa1?";??
String?sql2?=?"unlock?tables";??
try?{??
this.pstmt?=?conn.prepareStatement(sql);??
this.pstmt1?=?conn.prepareStatement(sql1);??
this.pstmt2?=?conn.prepareStatement(sql2);??
pstmt.executeQuery();??
pstmt1.executeQuery();??
pstmt2.executeQuery();??
}?catch?(Exception?e)?{??
System.out.println("異常"?+?e.getMessage());??
}??
}
對于read lock 和 write lock官方說明:
1.如果一個線程獲得一個表的READ鎖定,該線程(和所有其它線程)只能從該表中讀取。
如果一個線程獲得一個表的WRITE鎖定,只有保持鎖定的線程可以對表進(jìn)行寫入。
其它的線程被阻止,直到鎖定被釋放時為止。
2.當(dāng)您使用LOCK TABLES時,您必須鎖定您打算在查詢中使用的所有的表。
雖然使用LOCKTABLES語句獲得的鎖定仍然有效,但是您不能訪問沒有被此語句鎖定的任何的表。
同時,您不能在一次查詢中多次使用一個已鎖定的表——使用別名代替,
在此情況下,您必須分別獲得對每個別名的鎖定。
對與read lock 和 write lock個人說明:
1.read lock 和 write lock 是線程級(表級別).
2.在同一個會話中加了read lock鎖. 只能對這個表進(jìn)行讀操作.對這個表以外的任何表都無法進(jìn)行增、刪、改、查的操作.
但是在不同會話中,只能對加了read lock的表進(jìn)行讀操作.但可以對read lock以外的表進(jìn)行增、刪、改、查的操作.
3.在同一個會話中加了write lock鎖.只能對這個表進(jìn)行讀、寫操作.對這個表以外的任何表都無法進(jìn)行增、刪、改、查的操作.
但是在不同會話中,無法對加了write lock的表進(jìn)行讀、寫操作.但可以對write lock以外的表進(jìn)行增、刪、改、查的操作.
4.如果表中使用了別名.(SELECT * FROM aa1 AS byname_table)
在對aa1加鎖時,必須把別名加上去(lock tables aa1 as byname_table read)
在同一個會話中.必須使用別名進(jìn)行查詢.
在不同的會話中.可以不需要使用別名進(jìn)行查詢.
5.在多個會話中可以對同一個表進(jìn)行l(wèi)ock read操作.但不能在多個會話中對同一個表進(jìn)行l(wèi)ock write操作(這些鎖將等待已鎖的表釋放自身的線程鎖)
如果多個會話對同一個表進(jìn)行l(wèi)ock read操作.那么在這些會話中,也只能對以鎖的表進(jìn)行讀操作.
6.如果要你鎖住了一個表,需要嵌套查詢.你必須使用別名,并且,要鎖定別名.
例如.lock table aa1 read ,aa1 as byname_table read;
select * from aa1 where id in (select * from aa1 as xx??where id=2);
7.解鎖必須用unlock tables;
另:
在JAVA程序中,要想解鎖,需要調(diào)用 unlock tables來解鎖.
如果沒有調(diào)用unlock tables.
關(guān)閉connection 、程序結(jié)束 、調(diào)用GC 都能解鎖.
方法2:用記錄鎖鎖表.
public?void?test()?{??
String?sql?=?"select?*?from?aa1?for?update";???
//?select?*?from?aa1?lock?in?share?mode;???
try?{??
conn.setAutoCommit(false);??
this.pstmt?=?conn.prepareStatement(sql);??
pstmt.executeQuery();??
}?catch?(Exception?e)?{??
System.out.println("異常"?+?e.getMessage());??
}??
}
1.for update 與 lock in share mode 屬于行級鎖和頁級鎖
2.for update 排它鎖,lock in share mode 共享鎖
3.對于記錄鎖.必須開啟事務(wù).
4.行級鎖定事實(shí)上是索引記錄的鎖定.只要是用索引掃描的行(或沒索引全表掃描的行),都將被鎖住.
5.在不同的隔離級別下還會使用next-key locking算法.即所掃描的行之間的“間隙”也會也鎖住(在Repeatable read和Serializable隔離級別下有間隙鎖).
6.在mysql中共享鎖的含義是:在被共享鎖鎖住的行,即使內(nèi)容被修改且并沒有提交.在另一個會話中依然看到最新修改的信息.
在同一會話中加上了共享鎖.可以對這個表以及這個表以外的所有表進(jìn)行增、刪、改、查的操作.
在不同的會話中.可以查到共享鎖鎖住行的最新消息.但是在Read Uncommitted隔離級別下不能對鎖住的表進(jìn)行刪,
改操作.(需要等待鎖釋放才能操作...)
在Read Committed隔離級別下不能對鎖住的表進(jìn)行刪,改操作.(需要等待鎖釋放才能操作...)
在Repeatable read隔離級別下不能對鎖住行進(jìn)行增、刪、改操作.(需要等待鎖釋放才能操作...)
在Serializable隔離級別下不能對鎖住行進(jìn)行增、刪、改操作.??(需要等待鎖釋放才能操作...)
7.在mysql中排他鎖的含義是:在被排它鎖鎖住的行,內(nèi)容修改并沒提交,在另一個會話中不會看到最新修改的信息。
在不同的會話中.可以查到共享鎖鎖住行的最新消息.但是Read Uncommitted隔離級別下不能對鎖住的表進(jìn)行刪,
改操作.(需要等待鎖釋放才能操作...)
在Read Committed隔離級別下不能對鎖住的表進(jìn)行刪,改操作.(需要等待鎖釋放才能操作...)
在Repeatable read隔離級別下不能對鎖住行進(jìn)行增、刪、改操作.(需要等待鎖釋放才能操作...)
在Serializable隔離級別下不能對鎖住行進(jìn)行增、刪、改操作. (需要等待鎖釋放才能操作...)
8.在同一個會話中的可以疊加多個共享鎖和排他鎖.在多個會話中,需要等待鎖的釋放.
9.SQL中的update 與 for update是一樣的原理.
10.等待超時的參數(shù)設(shè)置:innodb_lock_wait_timeout=50 (單位秒).
11.任何可以觸發(fā)事務(wù)提交的命令,都可以關(guān)閉共享鎖和排它鎖.
1.凡使用synchronized標(biāo)記的方法,比如 public synchronized void func1() { .... },則同時只有一個線程能夠運(yùn)行這個方法。比如,線程1正在運(yùn)行func1,則其他線程需要運(yùn)行func1的話,會卡住,等線程1運(yùn)行func1結(jié)束后,其他線程中,才會有一個幸運(yùn)兒成功爭取到運(yùn)行func1的資格,然后這個幸運(yùn)兒線程開始運(yùn)行func1。沒有爭取到運(yùn)行資格的其他線程,會繼續(xù)等待。
2.你的例子中,被鎖定的是 方法 m1,而不是屬性b。所以,m1的synchronized加鎖操作,與b沒有半點(diǎn)毛錢關(guān)系。
3.要實(shí)現(xiàn)你的鎖b想法,其實(shí)很簡單。去買一件貞操寶甲來就行了。開玩笑,哈哈。要鎖b,把main方法里的tt.m2()修改為tt.m1()。
4.以后別用“b”作為變量,總覺得怪怪了。也許你現(xiàn)在還沒長大,很單純。但大人的世界里,“b”是一種不文雅但又對人類的未來有重要作用的東西。建議用cb來代替b。
對象是一個鎖標(biāo)志。按照先到先得的原則,如果有多個線程都會執(zhí)行代碼,并使用同一個對象作為鎖,
synchronize(對象){ .... }
那么,先執(zhí)行這段代碼的那個線程,將會獲得這個對象鎖,而當(dāng)這個線程執(zhí)行這段代碼的時候,其他線程也是使用這個對象作為鎖的,就不能執(zhí)行這段代碼,知道最初得到這個鎖的線程運(yùn)行完這段代碼,然后再把鎖分配給下一個線程執(zhí)行。
Java中文件加鎖機(jī)制如下:
在對文件操作過程中,有時候需要對文件進(jìn)行加鎖操作,防止其他線程訪問該文件。對文件的加鎖方法有兩種:
第一種方法:使用RandomAccessFile類操作文件。
在java.io.RandomAccessFile類的open方法,提供了參數(shù)實(shí)現(xiàn)獨(dú)占的方式打開文件:
RandomAccessFile raf = new RandomAccessFile(file, "rws");
其中的“rws”參數(shù),rw代表讀取和寫入,s代表了同步方式,也就是同步鎖。這種方式打開的文件,就是獨(dú)占方式的。
第二種方法:使用sun.nio.FileChannel對文件進(jìn)行加鎖。
代碼:
RandomAccessFile raf = new RandomAccessFile("file.txt", "rw");
FileChannel fc = raf.getChannel();
FileLock fl = fc.tryLock();
if(fl.isValid())
System.out.println("You have got the file lock.");
以上是通過RandomAccessFile來獲得文件鎖的,方法如下:
代碼:
FileOutputStream fos = new FileOutputStream("file.txt");
FileChannel fc = fos.getChannel(); //獲取FileChannel對象
FileLock fl = fc.tryLock(); //or fc.lock();
if(null != fl)
System.out.println("You have got file lock.");
//TODO write content to file
//TODO write end, should release this lock
fl.release(); //釋放文件鎖
fos.close; //關(guān)閉文件寫操作
如果在讀文件操作的時候,對文件進(jìn)行加鎖,操作過程如下:
FileChannel也可以從FileInputStream中直接獲得,但是這種直接獲得FileChannel的對象直接去操作FileLock會報(bào)異常NonWritableChannelException,需要自己去實(shí)現(xiàn)getChannel方法,代碼如下:
private static FileChannel getChannel(FileInputStream fin, FileDescriptor fd) {
FileChannel channel = null;
synchronized(fin){
channel = FileChannelImpl.open(fd, true, true, fin);
return channel;
}
}
其實(shí),看FileInputStream時,發(fā)現(xiàn)getChannel方法與我們寫的代碼只有一個地方不同,即open方法的第三個參數(shù)不同,如果設(shè)置為false,就不能鎖住文件了。缺省的getChannel方法,就是false,因此,不能鎖住文件。
與java無關(guān),要用sql語句實(shí)現(xiàn)
前提目標(biāo)表要有索引,查詢要開啟事物,使用select * from tb with(updlock) where col = xxx將一行數(shù)據(jù)鎖住,其他連接不能再修改表
你的代碼我沒看,也沒運(yùn)行。
但我可以很明確的告訴你,你是沒有辦法控制線程的執(zhí)行順序的,不知道你學(xué)沒學(xué)操作系統(tǒng),等你學(xué)了線程調(diào)度你就知道為什么了,多線程的一個特點(diǎn)就是不可重現(xiàn)性。像sleep這些函數(shù)只能在一定程度上控制你的線程執(zhí)行,但根本不是絕對的。因?yàn)楫?dāng)線程1在sleep時,系統(tǒng)也不一定會調(diào)用另一線程。
還有加鎖也不是為了控制線程的執(zhí)行順序,它的目的是為了保護(hù)共享的互斥資源。