您的位置:首页 > 其它

从头认识多线程-2.2 synchronized持有对象锁与类锁的相同点

2016-04-24 22:33 337 查看
这一章节我们来讨论一下synchronized持有对象锁与类锁的相同点。
1.当所有方法都不使用同步的时候
代码清单

package com.ray.deepintothread.ch02.topic_2;

public class SynchInstance1 {
public static void main(String[] args) throws InterruptedException {
MyTestObjectOne myTestObjectOne = new MyTestObjectOne();
for (int i = 0; i < 5; i++) {
ThreadOne threadTwo = new ThreadOne(myTestObjectOne);
Thread thread = new Thread(threadTwo);
thread.setName("" + i);
thread.start();
}
}
}

class ThreadOne implements Runnable {

private MyTestObjectOne myTestObjectOne;

public ThreadOne(MyTestObjectOne myTestObjectOne) {
this.myTestObjectOne = myTestObjectOne;
}

@Override
public void run() {
try {
if (Integer.parseInt(Thread.currentThread().getName()) % 2 == 0) {
myTestObjectOne.test1();
} else {
myTestObjectOne.test2();
}

} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

class MyTestObjectOne {
public void test1() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " method test1 begin");
System.out.println(Thread.currentThread().getName() + " method test1 waiting");
Thread.sleep(200);
System.out.println(Thread.currentThread().getName() + " method test1 end");
}

public void test2() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " method test2 begin");
System.out.println(Thread.currentThread().getName() + " method test2 waiting");
Thread.sleep(200);
System.out.println(Thread.currentThread().getName() + " method test2 end");
}
}

输出:
0 method test1 begin
0 method test1 waiting
4 method test1 begin
4 method test1 waiting
2 method test1 begin
2 method test1 waiting
1 method test2 begin
1 method test2 waiting
3 method test2 begin
3 method test2 waiting
0 method test1 end
4 method test1 end
2 method test1 end
1 method test2 end
3 method test2 end

持有类锁的情况:

package com.ray.deepintothread.ch02.topic_3;

public class SynchInstance1 {
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 5; i++) {
ThreadOne threadTwo = new ThreadOne();
Thread thread = new Thread(threadTwo);
thread.setName("" + i);
thread.start();
}
}
}

class ThreadOne implements Runnable {

@Override
public void run() {
try {
if (Integer.parseInt(Thread.currentThread().getName()) % 2 == 0) {
MyTestObjectOne.test1();
} else {
MyTestObjectOne.test2();
}

} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

class MyTestObjectOne {
public static void test1() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " method test1 begin");
System.out.println(Thread.currentThread().getName() + " method test1 waiting");
Thread.sleep(200);
System.out.println(Thread.currentThread().getName() + " method test1 end");
}

public static void test2() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " method test2 begin");
System.out.println(Thread.currentThread().getName() + " method test2 waiting");
Thread.sleep(200);
System.out.println(Thread.currentThread().getName() + " method test2 end");
}
}

输出:

0 method test1 begin
0 method test1 waiting
2 method test1 begin
2 method test1 waiting
3 method test2 begin
3 method test2 waiting
1 method test2 begin
1 method test2 waiting
4 method test1 begin
4 method test1 waiting
2 method test1 end
3 method test2 end
0 method test1 end
1 method test2 end
4 method test1 end

从两个输出可以看见,方法是交叉的执行,没有任何同步在里面的

2.当所有方法都使用同步的时候
代码清单

package com.ray.deepintothread.ch02.topic_2;

public class SynchInstance2 {
public static void main(String[] args) throws InterruptedException {
MyTestObjectTwo myTestObjectTwo = new MyTestObjectTwo();
for (int i = 0; i < 5; i++) {
ThreadTwo threadTwo = new ThreadTwo(myTestObjectTwo);
Thread thread = new Thread(threadTwo);
thread.setName("" + i);
thread.start();
}
}
}

class ThreadTwo implements Runnable {

private MyTestObjectTwo myTestObjectTwo;

public ThreadTwo(MyTestObjectTwo myTestObjectTwo) {
this.myTestObjectTwo = myTestObjectTwo;
}

@Override
public void run() {
try {
if (Integer.parseInt(Thread.currentThread().getName()) % 2 == 0) {
myTestObjectTwo.test1();
} else {
myTestObjectTwo.test2();
}

} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

class MyTestObjectTwo {
public synchronized void test1() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " method test1 begin");
System.out.println(Thread.currentThread().getName() + " method test1 waiting");
System.out.println(Thread.currentThread().getName() + " method test1 end");
}

public synchronized void test2() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " method test2 begin");
System.out.println(Thread.currentThread().getName() + " method test2 waiting");
System.out.println(Thread.currentThread().getName() + " method test2 end");
}
}

输出:
1 method test2 begin
1 method test2 waiting
1 method test2 end
0 method test1 begin
0 method test1 waiting
0 method test1 end
2 method test1 begin
2 method test1 waiting
2 method test1 end
4 method test1 begin
4 method test1 waiting
4 method test1 end
3 method test2 begin
3 method test2 waiting
3 method test2 end

package com.ray.deepintothread.ch02.topic_3;

public class SynchInstance2 {
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 5; i++) {
ThreadTwo threadTwo = new ThreadTwo();
Thread thread = new Thread(threadTwo);
thread.setName("" + i);
thread.start();
}
}
}

class ThreadTwo implements Runnable {

@Override
public void run() {
try {
if (Integer.parseInt(Thread.currentThread().getName()) % 2 == 0) {
MyTestObjectTwo.test1();
} else {
MyTestObjectTwo.test2();
}

} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

class MyTestObjectTwo {
public static synchronized void test1() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " method test1 begin");
System.out.println(Thread.currentThread().getName() + " method test1 waiting");
System.out.println(Thread.currentThread().getName() + " method test1 end");
}

public static synchronized void test2() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " method test2 begin");
System.out.println(Thread.currentThread().getName() + " method test2 waiting");
System.out.println(Thread.currentThread().getName() + " method test2 end");
}
}

输出:
0 method test1 begin
0 method test1 waiting
0 method test1 end
1 method test2 begin
1 method test2 waiting
1 method test2 end
3 method test2 begin
3 method test2 waiting
3 method test2 end
2 method test1 begin
2 method test1 waiting
2 method test1 end
4 method test1 begin
4 method test1 waiting
4 method test1 end

从输出和debug发现,每一个方法都是按照顺序执行,同步起效
但是比较奇怪的是,每次都是整个方法执行完了才到下一个方法执行
按照平常的执行,应该是像上面一样,交叉的执行,因为我们使用多线程而且是访问不同的方法,如果同步是方法级别,应该可以想象到线程1访问test1的时候,我线程2同时可以访问test2,如果不是,那么synchronized持有的是锁不是方法级别的,而是对象级别或者类级别,而一般类级别对于的是静态方法和代码块。

3.特点
(1)所有同步方法只能按顺序执行,上面的例子有所演示
(2)synchronized只同步标记的方法,不标记的还是不同步

package com.ray.deepintothread.ch02.topic_2;

public class SynchInstance3 {
public static void main(String[] args) throws InterruptedException {
MyTestObjectThree myTestObjectThree = new MyTestObjectThree();
for (int i = 0; i < 5; i++) {
ThreadThree threadThree = new ThreadThree(myTestObjectThree);
Thread thread = new Thread(threadThree);
thread.setName("" + i);
thread.start();
}
}
}

class ThreadThree implements Runnable {

private MyTestObjectThree myTestObjectThree;

public ThreadThree(MyTestObjectThree myTestObjectThree) {
this.myTestObjectThree = myTestObjectThree;
}

@Override
public void run() {
try {
if (Integer.parseInt(Thread.currentThread().getName()) % 2 == 0) {
myTestObjectThree.test1();
} else {
myTestObjectThree.test2();
}

} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

class MyTestObjectThree {
public synchronized void test1() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " method test1 begin");
System.out.println(Thread.currentThread().getName() + " method test1 waiting");
System.out.println(Thread.currentThread().getName() + " method test1 end");
}

public void test2() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " method test2 begin");
System.out.println(Thread.currentThread().getName() + " method test2 waiting");
System.out.println(Thread.currentThread().getName() + " method test2 end");
}
}

输出:
0 method test1 begin
3 method test2 begin
3 method test2 waiting
3 method test2 end
1 method test2 begin
1 method test2 waiting
1 method test2 end
0 method test1 waiting
0 method test1 end
2 method test1 begin
2 method test1 waiting
2 method test1 end
4 method test1 begin
4 method test1 waiting
4 method test1 end

package com.ray.deepintothread.ch02.topic_3;

public class SynchInstance3 {
public static void main(String[] args) throws InterruptedException {
MyTestObjectThree myTestObjectThree = new MyTestObjectThree();
for (int i = 0; i < 5; i++) {
ThreadThree threadThree = new ThreadThree(myTestObjectThree);
Thread thread = new Thread(threadThree);
thread.setName("" + i);
thread.start();
}
}
}

class ThreadThree implements Runnable {

private MyTestObjectThree myTestObjectThree;

public ThreadThree(MyTestObjectThree myTestObjectThree) {
this.myTestObjectThree = myTestObjectThree;
}

@Override
public void run() {
try {
if (Integer.parseInt(Thread.currentThread().getName()) % 2 == 0) {
myTestObjectThree.test1();
} else {
myTestObjectThree.test2();
}

} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

class MyTestObjectThree {
public synchronized void test1() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " method test1 begin");
System.out.println(Thread.currentThread().getName() + " method test1 waiting");
System.out.println(Thread.currentThread().getName() + " method test1 end");
}

public void test2() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " method test2 begin");
System.out.println(Thread.currentThread().getName() + " method test2 waiting");
System.out.println(Thread.currentThread().getName() + " method test2 end");
}
}

输出:
0 method test1 begin
0 method test1 waiting
0 method test1 end
2 method test1 begin
2 method test1 waiting
2 method test1 end
1 method test2 begin
1 method test2 waiting
4 method test1 begin
4 method test1 waiting
4 method test1 end
1 method test2 end
3 method test2 begin
3 method test2 waiting
3 method test2 end

总结:这一章节我们讨论了synchronized持有锁的情况。

这一章节就到这里,谢谢
------------------------------------------------------------------------------------
我的github:https://github.com/raylee2015/DeepIntoThread

目录:/article/7548544.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: