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;}@Overridepublic void runTest() throws Throwable {    // TODO Auto-generated method stub    System.out.println(myname + " BEGIN");    while (true) {        gate.pass(myname, myaddress);    }}测试如下:
@Testpublic 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();}

p_w_picpath

 
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: