为实现线程互斥,我们一般会用到synchronized关键字来给方法,代码块进行加锁处理。
一:给方法进行加锁
直接在方法的前面的加synchronized关键字,给整个的方法上锁。
public synchronized void Outputer(String log) {
int len = log.length();
for (int i = 0; i < len; i++) {
System.out.print(log.charAt(i));
}
System.out.println();
}
二:给代码块加锁
public void Outputer2(String log) {
int len = log.length();
synchronized (this) {
for (int i = 0; i < len; i++) {
System.out.print(log.charAt(i));
}
System.out.println();
}
}
上述的代码块加锁的时候,用到了synchronized () {…} 这里应该注意到时,在括号中应该是多线程共有的对象,这里用到的是this,即该方法的应该是同一个对象,这样才能真正的起到加锁的 效果。括号中还可以用类.class.
下面以一个实例演示线程之间互斥与同步通讯
子线程打印10次后,主线程20次,然后这样循环打印50次。
public class TestSyn {
public static void main(String[] args) {
Bussines bussines=new Bussines();
/**
* 子线程
*/
new Thread(new Runnable() {
@Override
public void run() {
for(int i=1;i<=50;i++){
bussines.sub(i);
}
}
}).start();
/**
* 主线程
*/
for(int i=1;i<=50;i++){
bussines.main(i);
}
}
}
class Bussines{
private boolean isMain=false;
//子线程的同步方法
public synchronized void sub(int i){
while(isMain){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int j=1;j<=10;j++){
System.out.println("子线程的第"+i+"次,角标为"+j);
}
isMain=!isMain;
this.notify();
}
//主线程的同步方法
public synchronized void main(int i){
while(!isMain){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int j=1;j<=20;j++){
System.out.println("主线程的第"+i+"次,角标为"+j);
}
isMain=!isMain;
this.notify();
}
}