启动线程调用start() 方法,run()方法是线程启动后须要执行的方法。 1. 继承thread类 2. 实现runnable 接口 3. 实现callable 接口(call()方法,有返回值经过future对象的get()方法能够获取返回值,get()方法会阻塞,直到任务结果返回)
1. Callable规定的方法是call(),而Runnable规定的方法是run()。 2. Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。 3. call()方法可抛出异常,而run()方法是不能抛出异常的。 4. 运行Callable任务可拿到一个Future对象, Future表示异步计算的结果。 5. 它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。 6. 经过Future对象可了解任务执行状况,可取消任务的执行,还可获取任务执行的结果。 7. Callable是相似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务
经常使用的是 ThreadPoolExecutor 类 自定义 corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit, BlockingQueue数据库
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
线程池公式 :缓存
maximumPoolSize = 2 * corePoolSize = 4 * cpu线程数
Executors.new SingleThreadPoolExecutor(); 最大线程数为1 Executors.new FixedThreadPoolExecutor(5) :核心线程数 = 最大线程数 Executors.new CachedThreadPoolExecutor() :缓存线程池 Executors.new ScheduledThreadPoolExecutor(5) :延迟/周期性线程池
single和fixed阻塞队列最大为 Interger.MAX_VALUE [2的31次方];
cached 和scheduled 最大线程数为 Interger.MAX_VALUE [2的31次方];多线程
===========================================================================dom
// 获取锁 void lock() // 若是当前线程未被中断,则获取锁,能够响应中断 void lockInterruptibly() // 返回绑定到此 Lock 实例的新 Condition 实例 Condition newCondition() // 仅在调用时锁为空闲状态才获取该锁,能够响应中断 boolean tryLock() // 若是锁在给定的等待时间内空闲,而且当前线程未被中断,则获取锁 boolean tryLock(long time, TimeUnit unit) // 释放锁 void unlock()
tryLock()方法是有返回值的,它表示用来尝试获取锁,若是获取成功,则返回true;若是获取失败(即锁已被其余线程获取),则返回false,也就是说,这个方法不管如何都会当即返回(在拿不到锁时不会一直在那等待)。
tryLock(long time, TimeUnit unit)方法和tryLock()方法是相似的,只不过区别在于这个方法在拿不到锁时会等待必定的时间,在时间期限以内若是还拿不到锁,就返回false,同时能够响应中断。若是一开始拿到锁或者在等待期间内拿到了锁,则返回true。异步
要点 : 共享读,独占写
//返回用于读取操做的锁 Lock readLock() //返回用于写入操做的锁 Lock writeLock()
代码示例 :工具
// 读数据 public void get() { // 加读锁 lock.readLock().lock(); try { System.out.println(Thread.currentThread().getName() + " be ready to read data!"); Thread.sleep((long) (Math.random() * 1000)); System.out.println(Thread.currentThread().getName() + " have read data :" + data); } catch (InterruptedException e) { e.printStackTrace(); } finally { // 释放读锁 lock.readLock().unlock(); } } // 写数据 public void put(Object data) { // 加写锁 lock.writeLock().lock(); try { System.out.println(Thread.currentThread().getName() + " be ready to write data!"); Thread.sleep((long) (Math.random() * 1000)); this.data = data; System.out.println(Thread.currentThread().getName() + " have write data: " + data); } catch (InterruptedException e) { e.printStackTrace(); } finally { // 释放写锁 lock.writeLock().unlock(); } } }