您的位置:首页 > 其它

多线程synchronized和synchronized static方法的区别

2017-09-10 23:36 477 查看

synchronized static和synchronized 关键字

1.synchronized satic 方法,如果是一个方法加上static关键字和synchronized。static一定不属于任何对象,属于一个类。那么它锁的是当前类的对象的class对象。因为Java中无论一个类有多少个对象,这些对象会对应唯一一个Class对象,因为当前线程分别访问了同一个类的两个对象的static,synchronized方法时候。他们执行的顺序也是顺序的,也就是说一个线程先去执行方法,执行完毕后另一个线程开始。(非常重要)

2.synichronized关键字锁的是对象锁,

代码例子:

class Resource {
public synchronized void method1() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("method1 running...");
}

public synchronized void method2() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("method2 running...");
}

public synchronized static void method3() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("method3 running...");
}

public synchronized static void method4() {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("method4 running...");
}
}

//线程1-调用 synchronized方法
class Method1Thread extends Thread {

private Resource syncMethodTest;

public Method1Thread(Resource syncMethodTest) {
this.syncMethodTest = syncMethodTest;
}

@Override
public void run() {
syncMethodTest.method1();
}
}

//线程2-调用 synchronized方法
class Method2Thread extends Thread {

private Resource resource;

public Method2Thread(Resource syncMethodTest) {
this.resource = syncMethodTest;
}

@Override
public void run() {
resource.method2();
}
}

//线程3-调用 synchronized static方法
class Method3Thread extends Thread {

private Resource syncMethodTest;

public Method3Thread(Resource syncMethodTest) {
this.syncMethodTest = syncMethodTest;
}

@Override
public void run() {
syncMethodTest.method3();
}
}

//线程4-调用 synchronized static方法
class Method4Thread extends Thread {

private Resource syncMethodTest;

public Method4Thread(Resource syncMethodTest) {
this.syncMethodTest = syncMethodTest;
}

@Override
public void run() {
syncMethodTest.method4();
}
}


测试类:

/**
* Created by qianyi on 2017/9/9.
*/
public class StaticSynicTest {

public static void main(String[] args) {
Resource resource = new Resource();
Resource resource1 = new Resource();
//访问synchronized方法
Thread t1 = new Method1Thread(resource);
//访问synchronized方法
Thread t2 = new Method2Thread(resource);
//访问synchronized static方法
Thread t3 = new Method3Thread(resource);
//访问synchronized static方法
Thread t4 = new Method4Thread(resource);
//访问synchronized static方法
Thread t6 = new Method4Thread(resource1);
//访问synchronized 方法
Thread t5 = new Method2Thread(resource1);
/**
* 都是对同一个实例的synchronized域访问,因此不能被同时访问,
*/
//        t1.start();
//        t2.start();

/**
*是针对不同实例的,实例有两个,针对的不同的resource和resource1,因此可以同时被访问
*/
//        t1.start();
//        t5.start();

/**
*t1锁的是对象锁,t4锁的是Class锁。可以同时访问。
*/
//        t4.start();
//        t1.start();
/**
* t4和t6分别操作的资源不同,但是锁的是class锁,所以不可以同时访问
*/
//        t4.run();
//        t6.run();
}
}


总结

1.synchronized 与static synchronized锁的范围不同,synchronized锁的是对象,static synchronized锁是class对象,两个互相不受影响。可以同时被访问。

2.synchronized static防止多个线程同时访问某一个方法。上面的例子是防止多个线程同时method3 和method4,即使操作资源的不同,因为锁的是Resource.class。class在真个内存中之后一个。所以多个线程不能同时访问。

3.synchronized锁的是对象。针对同一个实例(同一个对象),一定是同一个实例,多个线程不能同时访问。如果是不同的实例,那么也可以同时访问,锁的是对象(Resrouce的实例,针对同一个实例的多个线程访问必须遵守顺序)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多线程 static 区别