一段多线程锁机制的代码,看完你会提高不少。
2016-01-08 12:56
465 查看
最近看到一段很有意思的代码,先贴出来。
线程基础不好的相信已经看晕了,没关系,实践是检验真理的唯一标准,下面我们看在JDK1.6下面的运行结果:
下面开始分析我们的代码:
首先Thread-0是我们的MyThread线程,Thread-1是MyThread1线程。
程序启动Thread-0,m1方法被调用打印m1-1
wait方法使线程对象放弃对象锁,等待被唤醒Thread-0线程被挂起,等待其它线程唤醒,Thread-1线程执行,m2 方法被调用;
打印m2-1,notifyAll()唤醒所有的线程,Thread-0被唤醒,但notifyall()不放开对象锁,Thread-1继续执行,打印m2-2;
sleep方法使当前线程停止执行,放弃cpu时间片,让其他线程执行,但sleep方法不会使当前线程放弃锁,故m2 挂起, 1秒过后,打印m2-3,m2-4;
由于m2 持有MyClass1的锁,m2中的m1 方法可以继续执行,打印m1-1,但是由于没有释放锁,此时的线程还是在Thread-1中;
之后Thread-1遇到wait 方法使线程放弃对象锁,等待被唤醒,Thread-1被挂起,由于m2中的notifyall()已经唤醒Thread-0,所以Thread-0 开始继续执行,打印m1-2;
之后sleep方法使线程Thread-0 挂起,但不会放弃对象锁,1秒过后,继续打印m1-3,m1-4;
之后继续调用m2方法,注意此时线程仍是Thread-0,依次打印m2-1,不释放锁线程不变继续打印m2-2,m2-3,m2-4,调用m1方法,打印m1-1,这时遇到wait()Thread-0被挂起,Thread-1执行,紧接上次Thread-1停止的地方m1-1之后,打印m1-2。注意是Thread-1线程下。
重复以上过程,直至线程StackOverflowError退出。
多线程学习之路:站在大牛的肩膀上
http://blog.csdn.net/fenglibing/article/details/6278883 多线程各个方法介绍。
http://blog.psjay.com/posts/summary-of-java-concurrency-one-thread-fundation/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io Java并发总结(一):线程基础
http://blog.psjay.com/posts/summary-of-java-concurrency-two-synchronized-and-atomicity/ Java并发总结(二):同步与原子性
http://blog.psjay.com/posts/summary-of-java-concurrency-three-interrupt/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io Java并发总结(三):中断线程
http://blog.psjay.com/posts/summary-of-java-concurrency-four-collaboration/ Java并发总结(四):线程的协作
/** * * sleep(); 休眠,不会丢失任何监视器的所有权 * wait(); 等待,释放对监视器的所有权 * notice(); Wakes up a single thread that is waiting on this object's monitor * notifyAll(); Wakes up all threads that are waiting on this object's monitor. * synchronized: 加锁同步,实际上就是并行执行串行化 * @author Administrator * */ public class Test { public static void main(String[] args) { MyClass1 myClass = new MyClass1(); new MyThread(myClass).start(); new MyThread1(myClass).start(); } } class MyClass1 { public synchronized void m1() { System.out.println("m1-1"); try { // wait():当前线程等待,直到另一个线程调用notify()或者notifyAll(); // 执行wait()方法后释放对监视器(myClass.m1())的所有权,也就是释放锁 this.wait(); // 暂停改当前线程,并且会释放锁 } catch (Exception e) { e.printStackTrace(); } System.out.println("m1-2"); try { Thread.sleep(1000); // m1和m2同时暂停1秒钟 System.out.println("m1-3"); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("m1-4"); m2(); } public synchronized void m2() { System.out.println("m2-1"); // 唤醒m1,但是并不释放锁synchronized // Wakes up all threads that are waiting on this object's monitor this.notifyAll(); System.out.println("m2-2"); try { // 当前正在执行的线程休眠,线程不丢失任何监视器的所有权,也就是不会释放锁 Thread.sleep(1000); System.out.println("m2-3"); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("m2-4"); m1(); } } class MyThread extends Thread { private MyClass1 myClass; public MyThread(MyClass1 myClass){ this.myClass = myClass; } @Override public void run() { myClass.m1(); } } class MyThread1 extends Thread { private MyClass1 myClass; public MyThread1(MyClass1 myClass){ this.myClass = myClass; } @Override public void run() { try { // 暂停10毫秒是为了让m1先执行wait Thread.sleep(10); } catch (InterruptedException e1) { e1.printStackTrace(); } myClass.m2(); } }
线程基础不好的相信已经看晕了,没关系,实践是检验真理的唯一标准,下面我们看在JDK1.6下面的运行结果:
[test] 2011-03-19 09:25:25 [Thread-0] :m1-1 [test] 2011-03-19 09:25:25 [Thread-1] :m2-1 [test] 2011-03-19 09:25:25 [Thread-1] :m2-2 [test] 2011-03-19 09:25:26 [Thread-1] :m2-3 [test] 2011-03-19 09:25:26 [Thread-1] :m2-4 [test] 2011-03-19 09:25:26 [Thread-1] :m1-1 [test] 2011-03-19 09:25:26 [Thread-0] :m1-2 [test] 2011-03-19 09:25:27 [Thread-0] :m1-3 [test] 2011-03-19 09:25:27 [Thread-0] :m1-4 [test] 2011-03-19 09:25:27 [Thread-0] :m2-1 [test] 2011-03-19 09:25:27 [Thread-0] :m2-2 [test] 2011-03-19 09:25:28 [Thread-0] :m2-3 [test] 2011-03-19 09:25:28 [Thread-0] :m2-4 [test] 2011-03-19 09:25:28 [Thread-0] :m1-1 [test] 2011-03-19 09:25:28 [Thread-1] :m1-2 [test] 2011-03-19 09:25:29 [Thread-1] :m1-3 [test] 2011-03-19 09:25:29 [Thread-1] :m1-4 [test] 2011-03-19 09:25:29 [Thread-1] :m2-1 [test] 2011-03-19 09:25:29 [Thread-1] :m2-2 [test] 2011-03-19 09:25:30 [Thread-1] :m2-3 [test] 2011-03-19 09:25:30 [Thread-1] :m2-4 [test] 2011-03-19 09:25:30 [Thread-1] :m1-1 [test] 2011-03-19 09:25:30 [Thread-0] :m1-2 [test] 2011-03-19 09:25:31 [Thread-0] :m1-3 [test] 2011-03-19 09:25:31 [Thread-0] :m1-4 [test] 2011-03-19 09:25:31 [Thread-0] :m2-1 [test] 2011-03-19 09:25:31 [Thread-0] :m2-2 [test] 2011-03-19 09:25:32 [Thread-0] :m2-3 [test] 2011-03-19 09:25:32 [Thread-0] :m2-4 [test] 2011-03-19 09:25:32 [Thread-0] :m1-1 [test] 2011-03-19 09:25:32 [Thread-1] :m1-2 [test] 2011-03-19 09:25:33 [Thread-1] :m1-3 [test] 2011-03-19 09:25:33 [Thread-1] :m1-4 [test] 2011-03-19 09:25:33 [Thread-1] :m2-1 [test] 2011-03-19 09:25:33 [Thread-1] :m2-2 [test] 2011-03-19 09:25:34 [Thread-1] :m2-3 [test] 2011-03-19 09:25:34 [Thread-1] :m2-4 [test] 2011-03-19 09:25:34 [Thread-1] :m1-1 [test] 2011-03-19 09:25:34 [Thread-0] :m1-2 [test] 2011-03-19 09:25:35 [Thread-0] :m1-3 [test] 2011-03-19 09:25:35 [Thread-0] :m1-4 [test] 2011-03-19 09:25:35 [Thread-0] :m2-1 [test] 2011-03-19 09:25:35 [Thread-0] :m2-2 [test] 2011-03-19 09:25:36 [Thread-0] :m2-3 [test] 2011-03-19 09:25:36 [Thread-0] :m2-4 [test] 2011-03-19 09:25:36 [Thread-0] :m1-1 [test] 2011-03-19 09:25:36 [Thread-1] :m1-2 [test] 2011-03-19 09:25:37 [Thread-1] :m1-3 [test] 2011-03-19 09:25:37 [Thread-1] :m1-4 [test] 2011-03-19 09:25:37 [Thread-1] :m2-1 [test] 2011-03-19 09:25:37 [Thread-1] :m2-2 [test] 2011-03-19 09:25:38 [Thread-1] :m2-3 [test] 2011-03-19 09:25:38 [Thread-1] :m2-4 [test] 2011-03-19 09:25:38 [Thread-1] :m1-1 [test] 2011-03-19 09:25:38 [Thread-0] :m1-2 [test] 2011-03-19 09:25:39 [Thread-0] :m1-3 [test] 2011-03-19 09:25:39 [Thread-0] :m1-4 [test] 2011-03-19 09:25:39 [Thread-0] :m2-1 [test] 2011-03-19 09:25:39 [Thread-0] :m2-2 [test] 2011-03-19 09:25:40 [Thread-0] :m2-3 [test] 2011-03-19 09:25:40 [Thread-0] :m2-4 [test] 2011-03-19 09:25:40 [Thread-0] :m1-1 [test] 2011-03-19 09:25:40 [Thread-1] :m1-2
下面开始分析我们的代码:
首先Thread-0是我们的MyThread线程,Thread-1是MyThread1线程。
程序启动Thread-0,m1方法被调用打印m1-1
wait方法使线程对象放弃对象锁,等待被唤醒Thread-0线程被挂起,等待其它线程唤醒,Thread-1线程执行,m2 方法被调用;
打印m2-1,notifyAll()唤醒所有的线程,Thread-0被唤醒,但notifyall()不放开对象锁,Thread-1继续执行,打印m2-2;
sleep方法使当前线程停止执行,放弃cpu时间片,让其他线程执行,但sleep方法不会使当前线程放弃锁,故m2 挂起, 1秒过后,打印m2-3,m2-4;
由于m2 持有MyClass1的锁,m2中的m1 方法可以继续执行,打印m1-1,但是由于没有释放锁,此时的线程还是在Thread-1中;
之后Thread-1遇到wait 方法使线程放弃对象锁,等待被唤醒,Thread-1被挂起,由于m2中的notifyall()已经唤醒Thread-0,所以Thread-0 开始继续执行,打印m1-2;
之后sleep方法使线程Thread-0 挂起,但不会放弃对象锁,1秒过后,继续打印m1-3,m1-4;
之后继续调用m2方法,注意此时线程仍是Thread-0,依次打印m2-1,不释放锁线程不变继续打印m2-2,m2-3,m2-4,调用m1方法,打印m1-1,这时遇到wait()Thread-0被挂起,Thread-1执行,紧接上次Thread-1停止的地方m1-1之后,打印m1-2。注意是Thread-1线程下。
重复以上过程,直至线程StackOverflowError退出。
多线程学习之路:站在大牛的肩膀上
http://blog.csdn.net/fenglibing/article/details/6278883 多线程各个方法介绍。
http://blog.psjay.com/posts/summary-of-java-concurrency-one-thread-fundation/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io Java并发总结(一):线程基础
http://blog.psjay.com/posts/summary-of-java-concurrency-two-synchronized-and-atomicity/ Java并发总结(二):同步与原子性
http://blog.psjay.com/posts/summary-of-java-concurrency-three-interrupt/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io Java并发总结(三):中断线程
http://blog.psjay.com/posts/summary-of-java-concurrency-four-collaboration/ Java并发总结(四):线程的协作
相关文章推荐
- Python3写爬虫(四)多线程实现数据爬取
- C#实现多线程的同步方法实例分析
- C#线程间不能调用剪切板的解决方法
- 浅谈chuck-lua中的多线程
- C#简单多线程同步和优先权用法实例
- C#多线程学习之(四)使用线程池进行多线程的自动管理
- C#多线程编程中的锁系统(三)
- C#线程同步的三类情景分析
- C#获取进程或线程相关信息的方法
- C#停止线程的方法
- C#子线程更新UI控件的方法实例总结
- C#多线程学习之(六)互斥对象用法实例
- C#线程队列用法实例分析
- 基于一个应用程序多线程误用的分析详解
- C#多线程学习之(三)生产者和消费者用法分析
- C#多线程学习之(一)多线程的相关概念分析
- C#多线程之Thread中Thread.IsAlive属性用法分析
- 分享我在工作中遇到的多线程下导致RCW无法释放的问题
- C#多线程编程之使用ReaderWriterLock类实现多用户读与单用户写同步的方法
- C#控制台下测试多线程的方法