这几天看结城浩的《java多线程设计模式》,跟着做一些习题,有几道题目很有意思,记录下自己的体会。
首先是题目(在原书212页,书尾有解答):
public class Main { public static void main(String[] args) { try { Blackhole.enter(new Object()); } catch (InterruptedException e) { e.printStackTrace(); } } }
public class Blackhole { public static void enter(Object obj) throws InterruptedException { System.out.println("1"); magic(obj); System.out.println("2"); synchronized (obj) { System.out.println("3"); } } private static void magic(Object obj){} }
代码很简单,要求写出magic()代码,使得输出是
1 2
不能出现3.
思路:很明显要想不输出3,magic()必须得到obj锁,且不能释放才行。我的答案:
private static void magic(final Object obj) throws InterruptedException { new Thread() { @Override public void run() { synchronized (obj) { while (true) { } } } }.start(); Thread.sleep(100);//略停片刻,确保新线程能先于主线程得到obj锁, //不加这句输出往往还是123 //这题的难点就在这里 }
显然sleep()用的很不专业,那就来看作者的答案吧
private static void magic(final Object obj) throws InterruptedException { Thread thread = new Thread() { @Override public void run() { synchronized (obj) { synchronized (this) { this.setName("LockNow"); this.notifyAll(); } while (true) { } } } }; synchronized (thread) { thread.setName(""); thread.start(); while (thread.getName().equals("")) { thread.wait(); } } }
作者的思路很巧妙,通过thread.name的值来处理2个线程的执行次序。
1. 创建一个内部Thread实例thread,先不start()
2. 然后由主线程获得thread锁,并启动thread线程,然后开始等待。
3. thread线程会去获得obj锁,获得obj锁之后,该线程会修改自己name,并通知主线程。
4. 主线程发现条件满足,继续执行
刚看到答案,有个很大疑问,主线程获得thread锁之后,启动thread线程,而thread线程为了修改name,必须获得自己的锁(否则运行时会报错java.lang.IllegalMonitorStateException),这不死锁了吗?
仔细一想又不会,因为新线程开启之后,如果新线程运行到synchronized (this)被阻挡而无法修改name,主线程肯定会进入wait,而wait时主线程释放thread锁,新线程就可继续往下跑。
短短几行代码,线程之间同步协调环环相扣,不得不佩服作者的功力!
相关推荐
在Java出现以前,似乎人人都在谈论线程,却很少有人使用它。用线程编程是技巧性很强的且不可移植。 而在Java中却完全不同。Java的线程工具易于使用,并且像Java中的其他东西一样可以在不同的平台之间移植。这是一件...
Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解
Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程
Java线程Java线程Java线程Java线程Java线程Java线程
Java线程:概念与原理 Java线程:创建与启动 Java线程:线程栈模型与线程的变量 Java线程:线程状态的转换 Java线程:线程的同步与锁 Java线程:线程的交互 Java线程:线程的调度-休眠 Java线程:线程的调度-优先级 ...
15个Java线程并发面试题和答案.docx,15个Java线程并发面试题和答案.docx 15个Java线程并发面试题和答案.docx,15个Java线程并发面试题和答案.docx
Java多线程习题Java多线程习题
JAVA线程练习题及答案.pdf
java基础之多线程的练习题,博客访问地址: http://blog.csdn.net/u014028392/article/details/76906801
Java 线程系列博文总结word化,编目如下,欢迎互相学习交流: Java线程:概念与原理 Java线程:创建与启动 Java线程:线程栈模型与线程的变量 Java线程:线程状态的转换 Java线程:线程的同步与锁 Java线程:...
java 线程java 线程java 线程java 线程java 线程java 线程java 线程java 线程java 线程
Java线程面试题Top50[参照].pdf
Java线程模块Java线程之秒表新手学习Java线程模块时,利用Java中设置线程的暂停间隔,做的简易秒表
java线程 线程 教程 java线程教程 java线程学习资料 本教程有什么内容? 本教程研究了线程的基础知识— 线程是什么、线程为什么有用以及怎么开始编写使用线程的简单 程序。 我们还将研究更复杂的、使用线程的应用...
java 线程Dump 分析工具: Java的TDA线程转储分析器是一个用于分析Sun Java VM生成的线程转储和堆信息的小型Swing GUI(目前用1.4测试)。它从提供的日志文件中解析线程转储和类直方图。它提供关于发现的线程转储的...
这是对Java多线程的一些相关练习题 包括选择 填空 简答 编程等题型
Java线程:概念与原理 2 一、操作系统中线程和进程的概念 2 二、Java中的线程 3 三、Java中关于线程的名词解释 3 四、线程的状态转换和生命周期 4 Java线程:创建与启动 7 Java线程:线程名称的设定及获取 10 Java...
java线程同步java线程同步java线程同步
JAVA多线程练习题的答案。都是一些基本的练习题。对初学者有帮助
分析java线程日志的工具,使用jstack把java线程日志dump下来,然后上传到该工具,就可以查看线程阻塞情况等信息。