JAVA线程的一些总结

1.避免过多的同步
// Page 196

import java.util.*;

public abstract class WorkQueue {
    private final List queue = new LinkedList();
    private boolean stopped = false;

    protected WorkQueue() { new WorkerThread().start(); }

    public final void enqueue(Object workItem) {
        synchronized (queue) {
            queue.add(workItem);
            queue.notify();
        }
    }

    public final void stop()  {
        synchronized (queue) {
            stopped = true;
            queue.notify();
        }
    }
    protected abstract void processItem(Object workItem)
        throws InterruptedException;

    // Broken - invokes alien method from synchronized block!
    private class WorkerThread extends Thread {
        public void run() {
            while (true) {  // Main loop
                synchronized (queue) {
                    try {
                        while (queue.isEmpty() && !stopped)
                            queue.wait();
                    } catch (InterruptedException e) {
                        return;
                    }

                    if (stopped)
                        return;

                    Object workItem = queue.remove(0);
                    try {
                        processItem(workItem); // Lock held!
                    } catch (InterruptedException e) {
                        return;
                    }
                }
            }
        }
    }

/* COMMENTED OUT

    // Alien method outside synchronized block - "Open call" - Page 198
    private class WorkerThread extends Thread {
        public void run() {
            while (true) {  // Main loop
                Object workItem = null;
                synchronized (queue) {
                    try {
                        while (queue.isEmpty() && !stopped)
                            queue.wait();
                    } catch (InterruptedException e) {
                        return;
                    }
                    if (stopped)
                        return;
                    workItem = queue.remove(0);
                }
                try {
                    processItem(workItem); // No lock held
                } catch (InterruptedException e) {
                    return;
                }
            }
        }
    }

*/

}


// Page 198

class DeadlockQueue extends WorkQueue {
    protected void processItem(final Object workItem)
            throws InterruptedException {
        // Create a new thread that returns workItem to queue
        Thread child = new Thread() {
            public void run() { enqueue(workItem); }
        };
        child.start();
        child.join(); // Deadlock!

        // Will never print (unless open call version of WorkerThread is used
        System.out.println(workItem);
    }

    public static void main(String[] args) throws InterruptedException {
        WorkQueue queue = new DeadlockQueue();
        for (int i = 0; i < args.length; i++)
            queue.enqueue(args[i]);

        // Let items print for a while and then stop the queue
        Thread.sleep(1000);
        queue.stop();
    }
}



以上代码就出现了A释放锁需要等B执行完,但是B需要A的锁才能执行完毕。这样就出现了死锁。

解决方案就是把processItem拿到同步的外面来。


2.尽量不要依赖线程的调度,比如yield

3.不要使用线程组

你可能感兴趣的:(java,thread)