java-线程-线程的互斥技术
全部的代码如下
public class TraditionalThreadSynchronized {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new TraditionalThreadSynchronized().init();
}
private void init(){
/**内部类不能访问局部变量,所以这里要用final*/
final Outputer outputer = new Outputer();
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
Thread.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
outputer.output("GavinlinHere");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
Thread.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
outputer.output("JiaoZhaoHere");
}
}
}).start();
}
static class Outputer{
private String name;
/**
* 可以与outputsync同步,不可与static的同步
* @param name
*/
public void output(String name){
this.name = name;
int len = this.name.length();
synchronized(this){
for(int i = 0;i < len; i++){
System.out.print(this.name.charAt(i));
}
System.out.println();
}
}
public synchronized void outputsync(String name){
this.name = name;
int len = this.name.length();
for(int i = 0;i < len; i++){
System.out.print(this.name.charAt(i));
}
System.out.println();
}
/**
* 若想与output同步,必须output的锁为Outputer.class
* @param name
*/
public static synchronized void sOutputSync(String name){
int len = name.length();
for(int i = 0;i < len; i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
代码很长,但是可以分开来看
1.在main函数里就是生成了一个TraditionalThreadSynchronized对象并运行init()方法,为什么要这样做?因为Outputer是一个内部类,main是静态方法,不能调用内部类的实例对象(这又是为什么?因为java特性是内部类可以调用外部类的成员对象,而静态方法可以不创建对象就可以调用,这就产生了矛盾,什么矛盾?outputer找不到它的外部类TraditionalThreadSynchronized),所以需要这样处理,保证已经创建了TraditionalThreadSynchronized这个对象。
2.init方法生成了Outputer对象和启动了两个线程,同时调用outputer的方法,若果不做同步处理,结果就是打印出来的信息有几率是乱的。
3.outputer里有三个方法,要让第一个方法与其他两个方法之间同步,需要的锁是不一样的:第一个与第二个方法同步,只需在第一个方法的锁块加上this就可以了,也就是锁住了同一个对象。第一个与第三个方法同步需要在第一个方法的锁块里加上Outputer.class,即锁上同一份字节码。
浙公网安备 33010602011771号