要实现两个线程中打印的内容不错乱。
直接上代码:
package com.example.sync;
public class SyncTest {
public static void main(String[] args) {
final Show show = new Show();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
show.print1("codingishappy");
}
}
}).start();
new Thread(new Runnable() {
@Override
public 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() {
@Override
public void run() {
while (true) {
show.print1("codingishappy");
}
}
}).start();
new Thread(new Runnable() {
@Override
public 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();
}
}
}