《LINUX實戰:各種同步控制工具的使用》要點:
本文介紹了LINUX實戰:各種同步控制工具的使用,希望對您有用。如果有疑問,可以聯系我們。
共享鎖,運行多個線程同時臨界區
public void acquire()
public void acquireUninterruptibly()
public boolean tryAcquire()
public boolean tryAcquire(long timeout, TimeUnit unit)
public void release()
public
class
SemaphoreDemo {
? ?
private
static
final
int
THREAD_COUNT = 3;
? ?
private
static
ExecutorService threadPool = Executors
? ? ? ?
.newFixedThreadPool(THREAD_COUNT);
? ?
private
static
Semaphore s =
new
Semaphore(1);
? ?
public
static
void
main(String[] args) {
? ? ? ?
for
(
int
i=0;i<3;i++)
? ? ? ?
{
? ? ? ? ? ?
threadPool.execute(
new
Runnable() {
? ? ? ? ? ? ? ?
@Override
? ? ? ? ? ? ? ?
public
void
run() {
? ? ? ? ? ? ? ? ? ?
try
{
? ? ? ? ? ? ? ? ? ? ? ?
System.
out
.println(Thread.currentThread().getName()+
"start data"
);
? ? ? ? ? ? ? ? ? ? ? ?
Thread.sleep(2000);
? ? ? ? ? ? ? ? ? ? ? ?
s.acquire();
? ? ? ? ? ? ? ? ? ? ? ?
Thread.sleep(1000);
? ? ? ? ? ? ? ? ? ? ? ?
System.
out
.println(Thread.currentThread().getName()+
"save data"
);
? ? ? ? ? ? ? ? ? ? ? ?
s.release();
? ? ? ? ? ? ? ? ? ? ? ?
System.
out
.println(Thread.currentThread().getName()+
"release data"
);
? ? ? ? ? ? ? ? ? ? ? ?
Thread.sleep(2000);
? ? ? ? ? ? ? ? ? ? ? ?
System.
out
.println(Thread.currentThread().getName()+
"end data"
);
? ? ? ? ? ? ? ? ? ?
}
catch
(InterruptedException e) {
? ? ? ? ? ? ? ? ? ? ? ?
e.printStackTrace();
? ? ? ? ? ? ? ? ? ?
}
? ? ? ? ? ? ? ?
}
? ? ? ? ? ?
});
? ? ? ?
}
? ? ? ?
threadPool.shutdown();
? ?
}
}
?最后得出一個比較有意思的結論:Semaphore 像是一個共享的屋子,這個屋子里面只能有一定的人數,這個人數是所有人可以看到的,甚至與release()這個辦法,可以被別的線程進行調用,
一般使用acquire()? 與release() 這個之間的代碼只能有固定數量的線程存在,當然這種是當火線程進行獲取和釋放
ReadWriteLock是JDK5中提供的讀寫分別鎖
private static ReentrantReadWriteLock readWriteLock=new ReentrantReadWriteLock();
private static Lock readLock = readWriteLock.readLock();
private static Lock writeLock = readWriteLock.writeLock();
這個類如果沒有寫鎖的情況下,讀是無阻塞的,在必定程度上提高了程序的執行效率.
public
void
run() {?
? ? ? ? ? ? ? ?
//isRead自界說變量(判斷這個線程是讀還是寫)
? ? ? ? ? ? ? ?
if
(isRead) {?
? ? ? ? ? ? ? ? ? ? ? ?
//獲取讀鎖?
? ? ? ? ? ? ? ? ? ? ? ?
myLock.readLock().
lock
();?
? ? ? ? ? ? ? ? ? ? ? ?
System.
out
.println(
"讀"
);
? ? ? ? ? ? ? ? ? ? ? ?
//釋放讀鎖?
? ? ? ? ? ? ? ? ? ? ? ?
myLock.readLock().unlock();?
? ? ? ? ? ? ? ?
}
else
{?
? ? ? ? ? ? ? ? ? ? ? ?
//獲取寫鎖?
? ? ? ? ? ? ? ? ? ? ? ?
myLock.writeLock().
lock
();?
? ? ? ? ? ? ? ? ? ? ? ?
//執行現金業務?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
System.
out
.println(
"寫"
);
? ? ? ? ? ? ? ? ? ? ? ?
//釋放寫鎖?
? ? ? ? ? ? ? ? ? ? ? ?
myLock.writeLock().unlock();?
? ? ? ? ? ? ? ?
}?
? ? ? ?
}?
static final CountDownLatch end = new CountDownLatch(10);
end.countDown();? //這個辦法是子線程作完作業之后,調用的
end.await(); //主線等待指定數量的子線程完成作業,當所有子線程完成之后,主線程自動激活執行
public
class
CountDownLatchDemo {
? ?
private
static
CountDownLatch countDownLatch=
new
CountDownLatch(10);
? ?
public
static
void
main(String[] args) {
? ? ? ?
for
(
int
i=0;i<10;i++)
? ? ? ?
{
? ? ? ? ? ?
new
Thread(
new
Runnable() {
? ? ? ? ? ? ? ?
@Override
? ? ? ? ? ? ? ?
public
void
run() {
? ? ? ? ? ? ? ? ? ?
System.
out
.println(Thread.currentThread().getName()+
"work"
);
? ? ? ? ? ? ? ? ? ?
try
{
? ? ? ? ? ? ? ? ? ? ? ?
Thread.sleep(2000);
? ? ? ? ? ? ? ? ? ?
}
catch
(InterruptedException e) {
? ? ? ? ? ? ? ? ? ? ? ?
e.printStackTrace();
? ? ? ? ? ? ? ? ? ?
}
? ? ? ? ? ? ? ? ? ?
countDownLatch.countDown();
? ? ? ? ? ? ? ?
}
? ? ? ? ? ?
}).start();
? ? ? ?
}
? ? ? ?
new
Thread(
new
Runnable() {
? ? ? ? ? ?
@Override
? ? ? ? ? ?
public
void
run() {
? ? ? ? ? ? ? ?
try
{
? ? ? ? ? ? ? ? ? ?
countDownLatch.await();
? ? ? ? ? ? ? ? ? ?
System.
out
.println(Thread.currentThread().getName()+
"主線程start"
);
? ? ? ? ? ? ? ?
}
catch
(InterruptedException e) {
? ? ? ? ? ? ? ? ? ?
e.printStackTrace();
? ? ? ? ? ? ? ?
}
? ? ? ? ? ?
}
? ? ? ?
},
"main1"
).start();
? ?
}
}
?
public
class
CyclicBarrierDemo {
? ?
public
static
class
Soldier implements Runnable{
? ? ? ?
private
? String name;
? ? ? ?
private
final CyclicBarrier cyclicBarrier;
? ? ? ?
public
Soldier(String name,CyclicBarrier c) {
? ? ? ? ? ?
this
.name = name;
? ? ? ? ? ?
this
.cyclicBarrier=c;
? ? ? ?
}
? ? ? ?
@Override
? ? ? ?
public
void
run() {
? ? ? ? ? ? ?
try
{
? ? ? ? ? ? ? ? ?
//等待所有士兵到齊
? ? ? ? ? ? ? ? ?
System.
out
.println(name +
"報道"
);
? ? ? ? ? ? ? ? ?
cyclicBarrier.await();
? ? ? ? ? ? ? ? ? ?
dowork();
? ? ? ? ? ? ? ? ?
//等待所有士兵完成工作
? ? ? ? ? ? ? ? ?
cyclicBarrier.await();
? ? ? ? ? ? ?
}
? ? ? ? ? ? ?
catch
(Exception e)
? ? ? ? ? ? ?
{
? ? ? ? ? ? ? ? ?
e.printStackTrace();
? ? ? ? ? ? ?
}
? ? ? ?
}
? ? ? ?
public
void
dowork()
? ? ? ?
{
? ? ? ? ? ? ? ?
System.
out
.println(name +
"完成任務"
);
? ? ? ?
}
? ?
}
? ?
public
static
class
BarrierRun implements Runnable{
? ? ? ?
boolean flag;
? ? ? ?
int
? number;
? ? ? ?
public
BarrierRun(boolean flag,
int
number) {
? ? ? ? ? ?
this
.flag = flag;
? ? ? ? ? ?
this
.number = number;
? ? ? ?
}
? ? ? ?
@Override
? ? ? ?
public
void
run() {
? ? ? ? ? ?
if
(!flag)
? ? ? ? ? ?
{
? ? ? ? ? ? ? ?
System.
out
.println(
"士兵集合完畢"
);
? ? ? ? ? ? ? ?
flag=
true
;
? ? ? ? ? ? ? ?
System.
out
.println(
"開始執行任務"
);
? ? ? ? ? ?
}
? ? ? ? ? ?
else
{
? ? ? ? ? ? ? ?
System.
out
.println(
"任務完成"
);
? ? ? ? ? ?
}
? ? ? ?
}
? ?
}
? ?
public
static
void
main(String[] args) {
? ? ? ?
final?
int
N =10;
? ? ? ?
CyclicBarrier barrier =
new
CyclicBarrier(N,
new
BarrierRun(
false
,N));
? ? ? ?
System.
out
.println(
"集合隊伍"
);
? ? ? ?
for
(
int
i=0;i<N;i++)
? ? ? ?
{
? ? ? ? ? ?
new
Thread(
new
Soldier(
"士兵"
+i,barrier)).start();
? ? ? ?
}
? ?
}
}
每次CyclicBarrier 調用await()辦法之后,都會等待所有的子線程,之后執行CyclicBarrier 的Runnable的辦法?
unpark函數可以先于park調用.好比線程B調用unpark函數,給線程A發了一個“許可”,那么當線程A調用park時,它發現已經有“許可”了,那么它會馬上再繼續運行.
上面已經提到,unpark函數可以先于park挪用,這個正是它們的靈活之處.
一個線程它有可能在別的線程unPark之前,或者之后,或者同時調用了park,那么因為park的特性,它可以不用擔心本身的park的時序問題
本文永遠更新鏈接地址:
歡迎參與《LINUX實戰:各種同步控制工具的使用》討論,分享您的想法,維易PHP學院為您提供專業教程。