尝试从提问中发现关于线程的知识
问:同步方法和非同步方法是否可以同时调用?
答:可以。
解释:这里不贴具体代码,提示:银行如果存钱业务使用同步方法,查询余额使用非同步方法,那么就有可能产生脏读(DirtyRead)的情况,各位看官可自行编程验证。
问:一个同步方法可以调用另一个同步方法吗?
答:可以。一个线程已经拥有某个对象的锁,再次申请的时候仍然会得到该对象的锁,也就是说,synchronized获得的锁是可重入的。
解释:synchronized本身就是一个重入锁,同一线程可以重复获得同一对象的锁。注意:这种情况并不会产生死锁。
问:在继承中,子类可以调用父类的同步方法吗?
答:可以。
解释:这里不贴具体代码,各位看官可自行编程验证。
问:程序在执行过程中,如果出现异常,锁会被释放吗?
答:会。
解释:程序在执行过程中,如果出现异常,默认情况锁会被释放。所以,在并发处理的过程中,有异常要多加小心,不然可能会发生不一致的情况。比如,在一个web app处理过程中,多个servlet线程共同访问同一个资源,这时如果异常处理不合适,在第一个线程中抛出异常,其他线程就会进入同步代码区,有可能会访问到异常产生时的数据,因此要非常小心地处理同步业务逻辑中的异常。
问:volatile关键字是什么?
答:volatile关键字在c、java中都有,用于修饰变量,它在多处理器开发环境中保证了共享变量的“可见性”,即当一个线程修改一个共享变量时,另外一个变量能读到这个最新修改的值。A B线程都用到一个变量,java默认是A线程中保留一份copy,这样如果B线程修改了该变量,则A线程未必知道,使用volatile关键字,会让所有线程都会读到变量的修改值。
解释:这里不贴具体代码,各位看官可自行编程验证。注意,volatile并不能保证多个线程共同修改running变量时所带来的不一致问题,也就是说volatile不能替代synchronized。
问:AtomXXX类是什么?
答:AtomXXX类就是原子类,具有原子性。
解释:Java提供了一些原子类,例如AtomicInteger。在使用AtomicInteger类时,对这个原子对象的操作不会被其他操作打断。注意:AtomXXX类的多个方法并不构成原子性,这里不贴具体代码,各位看官可自行编程验证。
问:CountDownLatch是什么?
答:CountDownLatch是jdk1.5开始concurrent包里提供的并发编程工具类。
解释:
CountDownLatch的主要使用步骤是
1、初始化,指定线程个数,CountDownLatch latch = new CountDownLatch(3);
参数3代表线程的总数
2、每个线程执行后执行latch.countDown();,代表一个线程执行完成,待完成的线程数减1。
3、在线程添加latch.await();,阻塞该线程,等待其他子线程完成。
问:AtomXXX类是什么?
答:AtomXXX类就是原子类,具有原子性。
解释:Java提供了一些原子类,例如AtomicInteger。在使用AtomicInteger类时,对这个原子对象的操作不会被其他操作打断。注意:AtomXXX类的多个方法并不构成原子性,这里不贴具体代码,各位看官可自行编程验证。
注意:不要以字符串常量作为锁定对象,可能会两次锁定同一个对象,造成死锁!
问:reentrantlock(可重入锁)是什么?
答:reentrantlock就是可重入锁,和synchronized有相同的功能。
解释:reentrantlock和synchronized的区别在于,前者需要手动释放锁,一般是在finally里面进行释放;后者如果遇到异常,jvm会自动释放锁。而且,使用reentrantlock可以进行“尝试锁定”tryLock,这样无法锁定,或者在指定时间内无法锁定,线程可以决定是否继续等待。
注意:reentrantlock还被称为公平锁,即哪个线程等的时间长,会被优先开启。使用方法:new ReentrantLock(true),参数true表示这是公平锁,公平锁效率较低,但是比较公平。
问:lockInterrupted方法和lock方法的区别?
答:前者可被打断,后者不可被打断。
解释:Interrupted可被打断
问:ThreadLocal是什么?它和synchronized有什么区别?
答:ThreadLocal的作用是提供线程内的局部变量,这种变量在多线程环境下访问时能够保证各个线程里变量的独立性。ThreadLocal是使用空间换时间,synchronized是使用时间换空间。
解释:从ThreadLocal的名字上可以看到,这是个线程的局部变量。也就是说只有当前线程可以访问,既然是只有当前线程池可以访问的数据自然是线程安全的。