synchronized关键字一般称为互斥锁。在多线程并发执行情况下。如果没有加互斥锁就回出现各种问题。如下面的问题:
现在有两个字符串 duoxiancheng 和 esondf15.那么我想让两个线程交替去打印字符串打印的时候一个字符一个字符的打印,那么看会有什么问题?
1:定义打印字符串的方法:
publid void print(String str){
for(int i=0;i<str.length;i++){
System.out.print(str.charAt(i));
}
System.out.println("");
}
2:同时new两个线程调用打印字符串的方法。然后打印。
//business1和business2是创建的两个打印字符串的对象
new Thread(new Runnable(){
@override
public void run(){
business1.print("duoxiancheng");
business2.print("eson15dt");
}
})
3:跑的结果就是会出现一个线程字符串还没有打印完。另一个线程开始打印。字符串交织在一起。那么怎么办?
4:方法形式的对象锁
//business1和business2是创建的两个打印字符串的对象
new Thread(new Runnable(){
@override
public synchronized void run(){
business1.print("duoxiancheng");
business2.print("eson15dt");
}
})
为方法添加方法锁(互斥锁)线程在执行方法是否。拿到锁,执行完毕后释放锁。等待线程才能拿到锁并执行。这样就可以防止并发线程出现的问题
5另外一种写法如下:效果是一样的(代码块形式的对象锁)
public void output(String str){
synchronized (this){
for(int i=0;i<str.length();i++){
System.out.print(str.charAt(i));
}
System.out.println("");
}
}
6:如果方式是静态的改怎么做呢?这个时候加在方法上的锁叫类锁
public synchronized static void output2(String str){
for(int i=0;i<str.length();i++){
System.out.print(str.charAt(i));
}
System.out.println("");
}
这个时候如果同时执行5和6的代码虽然都上了锁。但是依然会出现并发问题。因为上的说不一样。那么需要修改成一样的
public void output(String str){
/**
*:代码块形势的锁
*
*/
synchronized (OutPuter.class){
for(int i=0;i<str.length();i++){
System.out.print(str.charAt(i));
}
System.out.println("");
}
}
类的字节码文件在一开始加载就有了。而且只有一份。所以可以实现互斥锁的功能。
总结一下:锁按照锁的对象可以分为:对象锁和类锁。按照在代码中的位置可以分为方法形式和代码块形式的
当多线程同时并发去执行一个任务的时候。如果任务只有一个。那么就要对这个任务上锁。说个线程轮休执行
等待---获得锁---执行---释放锁---等待---获得锁---执行---释放锁