在并发编程中,当存在共享数据(也称临界资源)和多条线程共同操作共享数据时,会出现线程安全的问题。为了保证多个线程在操作共享数据时,同一时刻有且只有一个线程可以进行操作,其他线程必须等到该线程处理完数据后再进行,java中对对象和类的操作可以使用synchronized:
1)java对象锁是用于对象实例(instance)方法,或者一个对象实例上的,
2)类锁是用于类的静态方法或者一个类的class对象上的。
对象锁的synchronized可以修饰对象的方法和代码块:
public class TestSynchronized {
private int shareParam=0;
public void method1(){
synchronized(TestSynchronized.this){ //修饰代码块,得到的实例对象锁
int i = 5;
while( i-- > 0){
shareParam++;
System.out.println(Thread.currentThread().getName() + " : " + i);
}
}
}
public synchronized void method2(){ //修饰方法,得到的实例对象锁
int i = 5;
while( i-- > 0)
{ shareParam++;
System.out.println(Thread.currentThread().getName() + " : " + i);
}
public static void main(String[] args) throws IOException {//进行测试
TestSynchronized myt2 = new TestSynchronized(); // myt2是TestSynchronized对象new的一个实例------1)
Thread test1 = new Thread( new Runnable() { public void run() { myt2.method1(); //myt2.method2();作用一样 } }, "method1" );
Thread test2 = new Thread( new Runnable() { public void run() { myt2.method1(); //myt2.method2();作用一样 } }, "method2" );
test1.start();
test2.start();
}
注意:对象锁只是对一个对象的多线程的同步,如上面示例线程test1和test2用的是TestSynchronized对象的同一个实例myt2,如改为:
TestSynchronized myt1 = new TestSynchronized();
TestSynchronized myt2 = new TestSynchronized();
Thread test1 = new Thread( new Runnable() { public void run() { myt1.method1(); } }, "thread1" );
Thread test2 = new Thread( new Runnable() { public void run() { myt2.method1(); } }, "thread2" );
则是两个对象,达不到想要的效果
类锁的synchronized可以修饰静态对象的方法和代码块:
public class TestSynchronized {
private int shareParam=0;
public void method1(){
synchronized(TestSynchronized.class){ //修饰代码块,得到的TestSynchronized的类锁
int i = 5;
while( i-- > 0){
shareParam++;
System.out.println(Thread.currentThread().getName() + " : " + i);
}
}
}
public static synchronized void method2(){ //修饰静态方法,TestSynchronized的类锁
int i = 5;
while( i-- > 0)
{ shareParam++;
System.out.println(Thread.currentThread().getName() + " : " + i);
}
public static void main(String[] args) throws IOException {//进行测试
TestSynchronized myt1 = new TestSynchronized();
TestSynchronized myt2 = new TestSynchronized();
Thread test1 = new Thread( new Runnable() { public void run() { myt1.method1(); } }, "thread1" );
Thread test2 = new Thread( new Runnable() { public void run() { myt2.method2(); } }, "thread2" );
test1.start();
test2.start();
}
注意:对象锁和类锁联合使用,达不到互斥锁的目的,因为对象锁是对象的一个实例instance的锁,而类锁是某个class的锁