对象锁:每个对象有一把锁,若对象的属性和函数被synchronized修饰的,则他们在被访问之前必须获得对象的锁。
类锁:每个类有一把锁,若类静态的属性和函数被synchronized修饰的,则他们在被访问之前必须获得对象的锁。
如果被synchronized修饰的函数,调用同一个对象或类被synchronized修饰的函数或属性时,会发生死锁。
package com.threadPool; import java.util.LinkedList; import java.util.logging.Logger; public class TestPool { private final static int nThreads = 100; private final static Mythread[] threads = new Mythread[nThreads]; private final static LinkedList queue = new LinkedList(); public TestPool(int nThreads) { PoolWorker poolWorker1 = new PoolWorker(); poolWorker1.setName("poolwork1"); poolWorker1.start(); PoolWorker poolWorker2 = new PoolWorker(); poolWorker2.setName("poolwork2"); poolWorker2.start(); for (int i=0; i<nThreads; i++) { threads[i] = new Mythread(); threads[i].setName("test "+i); // execute(threads[i]); /*try { Thread.sleep(10000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }*/ // threads[i].start(); } } private static void start(){ int i=100; while (i-- >0) { execute(threads[i]); /*try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }*/ } } public static void execute(Runnable r) { synchronized(queue) { queue.addLast(r); queue.notify(); } } private class PoolWorker extends Thread { public void run() { Runnable r; while (true) { synchronized(queue) { while (queue.isEmpty()) { try { System.out.print("pool work thread "+getName()+" wait \n"); queue.wait(); } catch (InterruptedException ignored) { } } r = (Runnable) queue.removeFirst(); } // If we don't catch RuntimeException, // the pool could leak threads try { System.out.print("pool work "+getName()+" and task is "+r.toString()+"\n"); r.run(); } catch (RuntimeException e) { // You might want to log something here } } } } private class Mythread extends Thread{ /* (non-Javadoc) * @see java.lang.Thread#run() */ @Override public void run() { // TODO Auto-generated method stub // super.run(); System.out.print("the"+getName()+"\n"); } } public static void main(String[] aString){ TestPool testPool = new TestPool(100); start(); } }这是一段简单的线程池的实例: 所有的用户任务放到queue队列中,线程池中有2个常驻工作线程,当queue中有任务时,工作线程就被唤醒,否则工作线程就进入等待状态。