第一種方式:使用Object的wait和notifyAll方法
package printABC.method1;
//第一種方法,使用Object的wait和notifyAll方法
public class TestPrint {
static int count = 0;
static final Object obj = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
synchronized (obj) {
if (count % 3 == 0) {
System.out.println("A");
count++;
obj.notifyAll();
} else
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
synchronized (obj) {
if (count % 3 == 1) {
System.out.println("B");
count++;
obj.notifyAll();
} else
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
synchronized (obj) {
if (count % 3 == 2) {
System.out.println("C");
count++;
obj.notifyAll();
} else
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
public void fun() {
t3.start();
t1.start();
t2.start();
}
public static void main(String[] args) {
TestPrint tp = new TestPrint();
long t1 = System.currentTimeMillis();
tp.fun();
while (true) {
if (System.currentTimeMillis() - t1 >= 10)// 運行10個毫秒
System.exit(0);
}
}
}
第二種方法:使用lock和condition
package printABC.method2;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//使用lock和Condition,更加靈活
public class LockPrint {
private static int count = 0;
private Lock lock = new ReentrantLock();
Condition c1 = lock.newCondition();
Condition c2 = lock.newCondition();
Condition c3 = lock.newCondition();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
lock.lock();
while (count % 3 != 0)
c1.await();
System.out.println("A");
count++;
c2.signal();// 喚醒條件2
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
lock.lock();
while (count % 3 != 1)
c2.await();
System.out.println("B");
count++;
c3.signal();// 喚醒條件3
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
});
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
lock.lock();
while (count % 3 != 2)
c3.await();
System.out.println("C");
count++;
c1.signal();// 喚醒條件1
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
});
public void fun() {
t3.start();
t1.start();
t2.start();
}
public static void main(String[] args) {
LockPrint lp = new LockPrint();
long t1 = System.currentTimeMillis();
lp.fun();
while (true) {
if (System.currentTimeMillis() - t1 >= 10)
System.exit(0);
}
}
}
第三種方法:使用concurrent的信號量Semaphore
package printABC.method3;
import java.util.concurrent.Semaphore;
//使用信號量
public class ConcurrentPrint {
// 共享資源個數都初始爲1
private static Semaphore s1 = new Semaphore(1);
private static Semaphore s2 = new Semaphore(1);
private static Semaphore s3 = new Semaphore(1);
Thread t1 = new Thread(new Runnable() {
public void run() {
while (true) {
try {
s1.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("A");
s2.release();
}
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
while (true) {
try {
s2.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("B");
s3.release();
}
}
});
Thread t3 = new Thread(new Runnable() {
public void run() {
while (true) {
try {
s3.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("C");
s1.release();
}
}
});
public void fun() throws InterruptedException {
// 先佔有輸出BC的線程的信號量計數
// 則只能從輸出A的線程開始。獲取信號量A,然後釋放B-獲取B-釋放C-獲取C-釋放A,由此形成循環
s2.acquire();
s3.acquire();
t2.start();
t3.start();
t1.start();
}
public static void main(String[] args) throws InterruptedException {
ConcurrentPrint cp = new ConcurrentPrint();
long t1 = System.currentTimeMillis();
cp.fun();
while (true) {
if (System.currentTimeMillis() - t1 >= 10)
System.exit(0);
}
}
}