线程之间的互斥主要是通过synchonized来实现的,注意synchonized关键字修饰的是同一个对象,下面来看一看代码实现:
1.错误的方法,synchonized修饰不同的对象
public class TraditionalSynchronized {
/**
* @param args
*/
public static void main(String[] args) {
new TraditionalSynchronized().init();
}
private void init(){
final Outputer output = new Outputer();//匿名内部类访问外部类,要加final
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
output.output("zhangsanshi");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
output.output("lisiguang");
}
}
}).start();
}
class Outputer {
public void output(String name){
int len = name.length();
synchronized(name){
for(int i= 0;i<len;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
}
2.改进的方式1(不是很严谨,但是没问题)
改写output方法
class Outputer {
String xxx = "";
public void output(String name){
int len = name.length();
synchronized(xxx){
for(int i= 0;i<len;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
执行后发现没有问题,因为不是很严谨,所以还要改进,得到改进2
static class Outputer {
public void output(String name){
int len = name.length();
synchronized(this){
for(int i= 0;i<len;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
有时为了省事,还可以这样做
public synchronized void output(String name){
int len = name.length();
for(int i= 0;i<len;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
思考一道问题,假如把output方法改成下面这样,又output方法与output3方法怎么实现互斥呢??
public static synchronized void output3(String name){
int len = name.length();
for(int i= 0;i<len;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
output3是静态方法,静态归结于类,想来想去同一个对象要实现互斥,就只有字节码对象,所以output方法可以这样改写
public void output(String name){
int len = name.length();
synchronized(Outputer.class){
for(int i= 0;i<len;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
这样就又实现了互斥