题目: 子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次, 接着再回到主线程又循环100次,如此循环50次.写出程序.
传统解法:
public class ThreadTest {
/**
*
* 子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次, 接着再回到主线程又循环100次,如此循环50次.写出程序.
*
* @param args
*/
public static void main(String[] args) {
final Business business = new Business();
for (int i = 1; i <= 50; i++) {
final int run = i;
new Thread(new Runnable() {
@Override
public void run() {
business.sub(run);
}
}).start();
business.main(i);
}
}
static class Business {
private boolean isSubTurn = true;
public synchronized void sub(int i) {
while (!isSubTurn) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 1; j <= 10; j++) {
System.out.println("sub run " + j + " in round " + i);
}
isSubTurn = false;
this.notify();
}
public synchronized void main(int i) {
while (isSubTurn) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 1; j <= 100; j++) {
System.out.println("main run " + j + " in round " + i);
}
isSubTurn = true;
this.notify();
}
}
}
使用Java5.0新特性:
用Lock替换synchronized
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
/**
*
* 子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次, 接着再回到主线程又循环100次,如此循环50次.写出程序.
*
* @param args
*/
public static void main(String[] args) {
final Business business = new Business();
for (int i = 1; i <= 50; i++) {
final int run = i;
new Thread(new Runnable() {
@Override
public void run() {
business.sub(run);
}
}).start();
business.main(i);
}
}
static class Business {
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
private boolean isSubTurn = true;
public void sub(int i) {
lock.lock();
try {
while (!isSubTurn) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 1; j <= 10; j++) {
System.out.println("sub run " + j + " in round " + i);
}
isSubTurn = false;
condition.signal();
} finally {
lock.unlock();
}
}
public void main(int i) {
lock.lock();
try {
while (isSubTurn) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 1; j <= 100; j++) {
System.out.println("main run " + j + " in round " + i);
}
isSubTurn = true;
condition.signal();
} finally {
lock.unlock();
}
}
}
}
使用BlockingQueue中的put和take完成互斥
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class BlockingQueueCommunication {
public static void main(String[] args) {
final Business business = new Business();
for (int i = 1; i <= 50; i++) {
final int temp = i;
new Thread(new Runnable() {
@Override
public void run() {
business.sub(temp);
}
}).start();
business.main(i);
}
}
static class Business {
BlockingQueue<Integer> queue1 = new ArrayBlockingQueue<Integer>(1);
BlockingQueue<Integer> queue2 = new ArrayBlockingQueue<Integer>(1);
{
try {
queue2.put(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void sub(int i) {
try {
queue1.put(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int j = 1; j <= 10; j++) {
System.out.println("sub run " + j + " in round " + i);
}
try {
queue2.take();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void main(int i) {
try {
queue2.put(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int j = 1; j <= 100; j++) {
System.out.println("main run " + j + " in round " + i);
}
try {
queue1.take();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}