作用:能够保证在同一时刻最多只有一个线程执行该代码,以保证并发效果的安全.
个人理解:Synchronized 修饰的代码就相当于加了一把锁,当多线程访问时,当前线程没有获取到锁对象,就不会执行那段代码.防止并发.
锁的方式有两种 对象锁 和 类锁 . 对象锁是对于实例出来的同一个对象来说.类锁是对于类来说的,实例出来多个对象,类锁一样有用.如果说实例出来两个对象,使用对象锁有可能还是会有并发操作,加锁没用.
对象锁的两种实现方式(方法锁默认当前this对象,同步代码块锁)
public class ObjectSync implements Runnable{
private static ObjectSync s1 = new ObjectSync();
/**
* 方法锁
*/
@Override
public void run() {
method();
}
public synchronized void method(){
System.out.println("当前线程执行名称."+Thread.currentThread().getName()+" is starting ");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前线程执行名称."+Thread.currentThread().getName()+" is finished ");
}
/**
* 同步代码块锁
*/
/*@Override
public void run() {
synchronized(this){
System.out.println("当前线程执行名称." + Thread.currentThread().getName() + " is starting ");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前线程执行名称." + Thread.currentThread().getName() + " is finished ");
}
}*/
public static void main(String[] args) throws InterruptedException{
Thread t1 = new Thread(s1);
Thread t2 = new Thread(s1);
t1.start();
t2.start();
while (t1.isAlive()||t2.isAlive()){
}
System.out.println("################finished!!!!!!!!!!!!!!!!");
}
}
类锁的两种实现方式(static形式 .class形式)
public class ClaseSync implements Runnable{
private static ClaseSync s1 = new ClaseSync();
private static ClaseSync s2 = new ClaseSync();
/**
* static形式
*/
/* @Override
public void run() {
method();
}
public static synchronized void method(){
System.out.println("当前线程执行名称."+Thread.currentThread().getName()+" is starting ");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前线程执行名称."+Thread.currentThread().getName()+" is finished ");
}*/
/**
* .class形式
*/
@Override
public void run() {
synchronized(ClaseSync.class){
System.out.println("当前线程执行名称." + Thread.currentThread().getName() + " is starting ");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前线程执行名称." + Thread.currentThread().getName() + " is finished ");
}
}
public static void main(String[] args) throws InterruptedException{
Thread t1 = new Thread(s1);
Thread t2 = new Thread(s2);
t1.start();
t2.start();
while (t1.isAlive()||t2.isAlive()){
}
System.out.println("################finished!!!!!!!!!!!!!!!!");
}
}
注意:static 修饰符表示静态的,可修饰字段、方法、内部类,其修饰的成员属于类,也就是说 static 修饰的资源属于类级别,而不是对象级别。这就可以理解类锁的static形式了.类级别的