Java中synchronized的使用注意

来源:互联网 发布:并发编程实践 编辑:程序博客网 时间:2024/05/18 20:52

要实现两个线程中打印的内容不错乱。

直接上代码:

package com.example.sync;public class SyncTest {public static void main(String[] args) {final Show show = new Show();new Thread(new Runnable() {@Overridepublic void run() {while (true) {show.print1("codingishappy");}}}).start();new Thread(new Runnable() {@Overridepublic void run() {while (true) {show.print2("lovethegirl");}}}).start();}static class Show {public synchronized void print1(String name) {for (int i = 0; i < name.length(); i++) {System.out.print(name.charAt(i));}System.out.println();}public synchronized static void print2(String name) {for (int i = 0; i < name.length(); i++) {System.out.print(name.charAt(i));}System.out.println();}}}

打印:

lovethegirshappy

可以看到这里打印的内容已经出现了错乱的,这个是我们不想出现的。

那么到底上面的代码出现了什么问题呢?其实上面的代码synchronized的使用上要注意一点,它必须要针对同一个对象,才能“锁住”代码块。

这里普通方法show1()使用的锁是类的实例,而static方法show2()使用的锁是Show.class字节码,这两个并非同一个对象。打个简单的比喻,

synchronized (xxx)这里的xxx对象就像一把锁,使用它将一个房价锁住其他人就不能进了。


改进只需要将show1的需要互斥的代码段,使用Show.class锁就可以了。

package com.example.sync;public class SyncTest {public static void main(String[] args) {final Show show = new Show();new Thread(new Runnable() {@Overridepublic void run() {while (true) {show.print1("codingishappy");}}}).start();new Thread(new Runnable() {@Overridepublic void run() {while (true) {show.print2("lovethegirl");}}}).start();}static class Show {public void print1(String name) {synchronized (Show.class) {for (int i = 0; i < name.length(); i++) {System.out.print(name.charAt(i));}System.out.println();}}public synchronized static void print2(String name) {for (int i = 0; i < name.length(); i++) {System.out.print(name.charAt(i));}System.out.println();}}}



0 0
原创粉丝点击