JUC线程高级---实现Callable方式创建线程和同步锁

**版权声明:本文为小斑马伟原创文章,转载请注明出处!
JUC线程高级---实现Callable方式创建线程和同步锁
文章图片

Java 5.0 在java.util.concurrent 提供了一个新的创建执行线程的方式:Callable 接口。Callable 接口类似于Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是Runnable 不会返回结果,并且无法抛出经过检查的异常。
Callable 需要依赖FutureTask ,FutureTask 也可以用作闭锁。

/* * 一、创建执行线程的方式三:实现 Callable 接口。 相较于实现 Runnable 接口的方式,方法可以有返回值,并且可以抛出异常。 * * 二、执行 Callable 方式,需要 FutureTask 实现类的支持,用于接收运算结果。FutureTask 是Future 接口的实现类 */ public class TestCallable {public static void main(String[] args) { ThreadDemo td = new ThreadDemo(); //1.执行 Callable 方式,需要 FutureTask 实现类的支持,用于接收运算结果。 FutureTask result = new FutureTask<>(td); new Thread(result).start(); //2.接收线程运算后的结果 try { Integer sum = result.get(); //FutureTask 可用于 闭锁 System.out.println(sum); System.out.println("------------------------------------"); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } class ThreadDemo implements Callable{@Override public Integer call() throws Exception { int sum = 0; for (int i = 0; i <= 100000; i++) { sum += i; }return sum; }

同步锁:在Java 5.0 之前,协调共享对象的访问时可以使用的机制只有synchronized 和volatile 。Java 5.0 后增加了一些新的机制,但并不是一种替代内置锁的方法,而是当内置锁不适用时,作为一种可选择的高级功能。
ReentrantLock 实现了Lock 接口,并提供了与synchronized 相同的互斥性和内存可见性。但相较于synchronized 提供了更高的处理锁的灵活性。
/* * 一、用于解决多线程安全问题的方式: * * synchronized:隐式锁 * 1. 同步代码块 * * 2. 同步方法 * * jdk 1.5 后: * 3. 同步锁 Lock * 注意:是一个显示锁,需要通过 lock() 方法上锁,必须通过 unlock() 方法进行释放锁 */ public class TestLock {public static void main(String[] args) { Ticket ticket = new Ticket(); new Thread(ticket, "1号窗口").start(); new Thread(ticket, "2号窗口").start(); new Thread(ticket, "3号窗口").start(); }class Ticket implements Runnable{private int tick = 100; private Lock lock = new ReentrantLock(); @Override public void run() { while(true){lock.lock(); //上锁try{ if(tick > 0){ try { Thread.sleep(200); } catch (InterruptedException e) { }System.out.println(Thread.currentThread().getName() + " 完成售票,余票为:" + --tick); } }finally{ lock.unlock(); //释放锁 } } }

【JUC线程高级---实现Callable方式创建线程和同步锁】Lock上锁之后 一定要是否锁。避免异常情况下没有释放锁。将释放锁lock.unlock()操作写到finally中。

    推荐阅读