锁
在并发环境下,解决共享资源冲突问题时,可以考虑使用锁机制。
synchronized同步
当使用同步块时,如果方法下的同步块都同步到一个对象上的锁,则所有的任务(线程)只能互斥的进入这些同步块。
举例说明:
1、Test1.java演示了4个线程(包括main线程)试图进入某个类的三个不同的方法的同步块中
线程1调用method1
线程2调用method2
线程3调用method3
main也调用method3
不仅仅线程3和main是互斥的,实际上4个线程都是互斥的,因为他们都同步到了一个对象上(当前对象 synchronized (this)),所以对它们的方法依然是互斥的。
2、Test2.java演示了2个线程(包括main线程)试图进入某个类的同一个同步方法中,另外两个线程进入非同步方法。
线程1调用同步方法method1
线程2调用method2
线程3调用method3
main调用同步方法method1
线程1和main是互斥的,
如果先启动线程1,则线程1,线程2,线程3是独立进行的。执行完线程1,才会执行main
如果先启动线程main,则main,线程2,线程3是独立进行的。执行完main,才会执行线程1
3、Test3.java演示了三个线程试图进入某个类的三个不同的方法的同步块中,这些同步块处在不同的方法中,并且是同步到三个不同的对象(synchronized (obj1),synchronized(obj2),synchronized (obj3)),所以这三个线程是独立进行的,并不是互斥的。
package com.jialin;
/**
* 抽象测试类
* @author jialin
*
*/
public abstract class AbstractTest {
public void Method1()
{}
public void Method2()
{}
public void Method3()
{}
}
package com.jialin;
import java.util.concurrent.TimeUnit;
/**
* 测试java 锁
* @author jialin
*
*/
public class Test1 extends AbstractTest{
public void Method1() {
//-----这一部分未加锁,可以运行到------begin---
System.out.println(Thread.currentThread().getName()
+ ":not synchronized part in Method1()");
//-----这一部分未加锁,可以运行到------end---
synchronized (this) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+ ":synchronized in Method1("+i+")");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void Method2() {
//-----这一部分未加锁,可以运行到------begin---
System.out.println(Thread.currentThread().getName()
+ ":not synchronized part in Method2()");
//-----这一部分未加锁,可以运行到------end---
synchronized (this) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+ ":synchronized in Method2("+i+")");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void Method3() {
//-----这一部分未加锁,可以运行到------begin---
System.out.println(Thread.currentThread().getName()
+ ":not synchronized part in Method3()");
//-----这一部分未加锁,可以运行到------end---
synchronized (this) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+ ":synchronized in Method3("+i+")");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
//初始化Test1对象
final AbstractTest ts = new Test1();
//线程1
Thread1 thread1=new Thread1(ts);
thread1.start();
//线程2
Thread2 thread2=new Thread2(ts);
thread2.start();
//线程3
Thread3 thread3=new Thread3(ts);
thread3.start();
//main线程
ts.Method3();
}
}
运行结果:
Thread-0:not synchronized part in Method1()
Thread-0:synchronized in Method1(0)
main:not synchronized part in Method3()
Thread-1:not synchronized part in Method2()
Thread-2:not synchronized part in Method3()
Thread-0:synchronized in Method1(1)
Thread-0:synchronized in Method1(2)
Thread-0:synchronized in Method1(3)
Thread-0:synchronized in Method1(4)
Thread-2:synchronized in Method3(0)
Thread-2:synchronized in Method3(1)
Thread-2:synchronized in Method3(2)
Thread-2:synchronized in Method3(3)
Thread-2:synchronized in Method3(4)
Thread-1:synchronized in Method2(0)
Thread-1:synchronized in Method2(1)
Thread-1:synchronized in Method2(2)
Thread-1:synchronized in Method2(3)
Thread-1:synchronized in Method2(4)
main:synchronized in Method3(0)
main:synchronized in Method3(1)
main:synchronized in Method3(2)
main:synchronized in Method3(3)
main:synchronized in Method3(4)
package com.jialin;
import java.util.concurrent.TimeUnit;
public class Test2 extends AbstractTest {
public synchronized void Method1() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+ ":synchronized in Method1("+i+")");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void Method2() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+ ":no synchronized in Method2("+i+")");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void Method3() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+ ":no synchronized in Method3("+i+")");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
// 初始化Test1对象
final AbstractTest ts = new Test2();
// 线程1
Thread1 thread1 = new Thread1(ts);
thread1.start();
// 线程2
Thread2 thread2 = new Thread2(ts);
thread2.start();
//线程3
Thread3 thread3=new Thread3(ts);
thread3.start();
// main线程
ts.Method1();
}
}
运行结果:
Thread-0:synchronized in Method1(0)
Thread-1:no synchronized in Method2(0)
Thread-2:no synchronized in Method3(0)
Thread-0:synchronized in Method1(1)
Thread-1:no synchronized in Method2(1)
Thread-2:no synchronized in Method3(1)
Thread-1:no synchronized in Method2(2)
Thread-0:synchronized in Method1(2)
Thread-2:no synchronized in Method3(2)
Thread-1:no synchronized in Method2(3)
Thread-0:synchronized in Method1(3)
Thread-2:no synchronized in Method3(3)
Thread-1:no synchronized in Method2(4)
Thread-2:no synchronized in Method3(4)
Thread-0:synchronized in Method1(4)
main:synchronized in Method1(0)
main:synchronized in Method1(1)
main:synchronized in Method1(2)
main:synchronized in Method1(3)
main:synchronized in Method1(4)
package com.jialin;
import java.util.concurrent.TimeUnit;
public class Test3 extends AbstractTest {
private Object obj1=new Object();
private Object obj2=new Object();
private Object obj3=new Object();
public void Method1() {
synchronized (obj1) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+ ":synchronized in Method1("+i+")");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void Method2() {
synchronized (obj2) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+ ":synchronized in Method2("+i+")");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void Method3() {
synchronized (obj3) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+ ":synchronized in Method3("+i+")");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
// 初始化Test1对象
final AbstractTest ts = new Test3();
// 线程1
Thread1 thread1 = new Thread1(ts);
thread1.start();
// 线程2
Thread2 thread2 = new Thread2(ts);
thread2.start();
//线程3
Thread3 thread3=new Thread3(ts);
thread3.start();
}
}
运行结果:
Thread-0:synchronized in Method1(0)
Thread-1:synchronized in Method2(0)
Thread-2:synchronized in Method3(0)
Thread-1:synchronized in Method2(1)
Thread-0:synchronized in Method1(1)
Thread-2:synchronized in Method3(1)
Thread-0:synchronized in Method1(2)
Thread-2:synchronized in Method3(2)
Thread-1:synchronized in Method2(2)
Thread-0:synchronized in Method1(3)
Thread-2:synchronized in Method3(3)
Thread-1:synchronized in Method2(3)
Thread-0:synchronized in Method1(4)
Thread-2:synchronized in Method3(4)
Thread-1:synchronized in Method2(4)
package com.jialin;
public class Thread1 extends Thread {
private AbstractTest ts;
public Thread1(AbstractTest ts)
{
this.ts=ts;
}
@Override
public void run() {
ts.Method1();
}
}
package com.jialin;
public class Thread2 extends Thread {
private AbstractTest ts;
public Thread2(AbstractTest ts) {
this.ts = ts;
}
@Override
public void run() {
ts.Method2();
}
}
package com.jialin;
public class Thread3 extends Thread {
private AbstractTest ts;
public Thread3(AbstractTest ts) {
this.ts = ts;
}
@Override
public void run() {
ts.Method3();
}
}