您的位置:首页 > 编程语言 > Java开发

javathreadpattern_01_singleThreadPattern

2013-05-04 15:54 295 查看
1.perface: singleThread 是单一线程模式:即在单一的时间片上只允许一个线程通过。2.service:code:demo01: 单人过门问题:情景如下:有一个独木桥,每次只允许一个人通过,现有三个人过桥,代码实现过桥循序 只要名字首字母和国家首字母相同即可通过Gate class:
public class Gate {
private int counter = 0;
private String name = "Nobody";
private String address = "Nowhere";
public synchronized void pass(String name, String address) {
this.counter++;
this.name = name;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
this.address = address;
check();
}
public synchronized String toString() {
return "No." + counter + ": " + name + ", " + address;
}
private void check() {
if (name.charAt(0) != address.charAt(0)) {
System.out.println("***** BROKEN ***** " + toString());
}
}
}
userThread如下:
public class testsingleThreadUserThread extends TestRunnable {
private final Gate gate;
private final String myname;
private final String myaddress;
public testsingleThreadUserThread(Gate gate, String myname, String myaddress) {
this.gate = gate;
this.myname = myname;
this.myaddress = myaddress;
}
@Override
public void runTest() throws Throwable {
// TODO Auto-generated method stub
System.out.println(myname + " BEGIN");
while (true) {
gate.pass(myname, myaddress);
}
}
测试如下:
@Test
public void singlethreadTest() throws Throwable {
System.out.println("Testing Gate, hit CTRL+C to exit.");
TestRunnable tr1, tr2, tr3;
Gate gate = new Gate();
tr1 = new testsingleThreadUserThread(gate, "Alice", "Alaska");
tr2 = new testsingleThreadUserThread(gate, "Bobby", "Brazil");
tr3 = new testsingleThreadUserThread(gate, "Chris", "Canada");
TestRunnable[] trs = { tr1,tr2,tr3 };
MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(trs);
mttr.runTestRunnables();
}


demo02:死锁(deadLock):情景: 桌子上的对应的spoon和fork,alice 和bob 同时去吃饭,很显然他们的必须同时取得spoon和fork才能吃饭。Tool:
public class Tool {
private final String name;
public Tool(String name) {
this.name = name;
}
public String toString() {
return "[ " + name + " ]";
}
}
public class EaterThreadTest extends TestRunnable {
private String name;
private final Tool lefthand;
private final Tool righthand;
public EaterThreadTest(String name, Tool lefthand, Tool righthand) {
this.name = name;
this.lefthand = lefthand;
this.righthand = righthand;
}
// public void run() {
// while (true) {
// eat();
// }
// }
public void eat() {
synchronized (lefthand) {
System.out.println(name + " takes up " + lefthand + " (left).");
synchronized (righthand) {
System.out.println(name + " takes up " + righthand
+ " (right).");
System.out.println(name + " is eating now, yam yam!");
System.out.println(name + " puts down " + righthand
+ " (right).");
}
System.out.println(name + " puts down " + lefthand + " (left).");
}
}
@Override
public void runTest() throws Throwable {
// TODO Auto-generated method stub
while (true) {
this.eat();
}
}
}
public class testMain {
@Test
public void testdeadlick() throws Throwable {
System.out.println("Testing EaterThread, hit CTRL+C to exit.");
Tool spoon = new Tool("Spoon");
Tool fork = new Tool("Fork");
TestRunnable tr1, tr2;
tr2 = (TestRunnable) new EaterThreadTest("Boby", spoon, fork);
tr1 = (TestRunnable) new EaterThreadTest("Alice", spoon, fork);

TestRunnable[] trs = { tr1, tr2 };
MultiThreadedTestRunner multiThreadedTestRunner = new MultiThreadedTestRunner(
trs);
multiThreadedTestRunner.runTestRunnables();
}
测试时,问题是:spoon和fork应该是一个整体,两个进程访问时,可能会将持有对方进程资源。也就是竞争不可剥夺资源。
也就是说:其作为整体资源才具有意义。
public class Pair {
private final Tool lefthand;
private final Tool righthand;
public Pair(Tool lefthand, Tool righthand) {
this.lefthand = lefthand;
this.righthand = righthand;
}
public String toString() {
return "[ " + lefthand + " and " + righthand + " ]";
}
}
demo03 :互斥对象为了解决共享临界区的资源问题,使用Mutex类来实现对临界资源的加锁和解锁。加锁时,标志该进程将要占用该资源。其他的进程则要等待。解锁时,表示无进程占用该资源,唤醒所有线程去占用资源。因此,在可能线程争用的方法中将逻辑进行先加锁后解锁处理即可。

public final class Mutex {
private boolean busy = false;
public synchronized void lock() {
while (busy) {
try {
wait();
} catch (InterruptedException e) {
}
}
busy = true;
}
public synchronized void unlock() {
busy = false;
notifyAll();
}
}
互斥对象补充
一个较为完善的互斥对象的结构:包含了一个使用数量,一个线程ID,一个计数器
使用数量是指有多少个线程在调用该对象,线程ID是指互斥对象维护的线程的ID
计数器表示当前线程调用该对象的次数:
public final class Mutex {
private long locks = 0;
private Thread owner = null;
public synchronized void lock() {
Thread me = Thread.currentThread();
while (locks > 0 && owner != me) {
try {
wait();
} catch (InterruptedException e) {
}
}
// locks == 0 || owner == me
owner = me;
locks++;
}
public synchronized void unlock() {
Thread me = Thread.currentThread();
if (locks == 0 || owner != me) {
return;
}
// locks > 0 && owner == me
locks--;
if (locks == 0) {
owner = null;
notifyAll();
}
}
}
3.reference:java多线程设计模式详解:4.enclosure download【notes】:测试环境为groboutils:

附件:http://down.51cto.com/data/2362768
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐