2021-05-12 14:32:11
各種同步控制工具的使用
Semaphore
概述
共用鎖,執行多個執行緒同時臨界區
主要介面
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
概述
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();
}
}
CountDownLatch
概述:
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();
}
}
CyclicBarrier
概述
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的方法
LockSupport
概述
unpark函數可以先於park呼叫。比如執行緒B呼叫unpark函數,給執行緒A發了一個“許可”,那麼當執行緒A呼叫park時,它發現已經有“許可”了,那麼它會馬上再繼續執行。
park和unpark的靈活之處
上面已經提到,unpark函數可以先於park呼叫,這個正是它們的靈活之處。
一個執行緒它有可能在別的執行緒unPark之前,或者之後,或者同時呼叫了park,那麼因為park的特性,它可以不用擔心自己的park的時序問題
本文永久更新連結地址:http://www.linuxidc.com/Linux/2017-05/144287.htm
相關文章