您的位置:首页 > 编程语言

一段多线程锁机制的代码,看完你会提高不少。

2016-01-08 12:56 465 查看
最近看到一段很有意思的代码,先贴出来。

/**
*
*      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并发总结(四):线程的协作
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多线程 线程