本文主要是介绍【并发】android中的synchronized,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
synchronized用于多线程访问,并且被修饰的部分不能同时被执行,是代码同步的一种方式。
1 使用synchronized修饰方法
1.1 synchronized修饰方法原理
- 过程:当多个线程同时访问被synchronized修饰的方法是,有且仅有一个线程可以被访问,当一个线程在访问时,其它线程只能等待。当一个线程访问完毕后,下一个线程才可以访问。
- 原理:当方法被synchronized修饰后,如果想要执行该方法就必须获得相应的锁。每个类有且仅有一个锁(针对静态方法),每个类的实例也是有且仅有一个锁。当多个线程在同时访问同一个方法时,执行该方法就必须获得相应的锁,同时锁只有一个,所以只能有一个线程可以获得锁,其它的线程必须等待该线程释放锁后才能获取到该锁。
- 进阶说明:由于每个类只有一个锁,所以当一个类中有多个方法被synchronized修饰时,在同一时间内只能有一个方法可以获得锁,所以只有一个被synchronized修饰的方法可以执行。
1.2 synchronized修饰方法示例
public void showDo(String msg){for(int i=0;i<1000000;i++){if (i%100000==0){System.out.println("打印结果"+msg+i/100000);}}}//使用new Thread(){@Overridepublic void run() {super.run();showDo("线程一");}}.start();new Thread(){@Overridepublic void run() {super.run();showDo("线程二");}}.start();
结果:
未加synchronized修饰方法,可以看到执行顺序是打乱的,无序的。加了synchronized后:
public synchronized void showDo(String msg){for(int i=0;i<1000000;i++){if (i%100000==0){System.out.println("打印结果"+msg+i/100000);}}}
结果
2 使用synchronized修饰代码块
2.1使用synchronized修饰代码块说明
当使用synchronized在修饰代码块的时候需要一个自定义锁,当在多线程访问代码块的时候,只要获得自定义锁就可以执行。自定义锁可以是一个类,也可以是一个实例(可以是Object的子类,也可以是当前类自己),当具有相同自定义锁时代码块会顺序执行,当锁不同的时候互不影响。
2.2 使用synchronized修饰代码块示例
private static String s1 = "";private static String s2 = "aa";public void showDo(String msg) {synchronized (s1){for (int i = 0; i < 1000000; i++) {if (i % 100000 == 0) {System.out.println("打印结果" + msg + i / 100000);}}}}public void showDo1(String msg) {synchronized (s2){for (int i = 0; i < 1000000; i++) {if (i % 100000 == 0) {System.out.println("打印" + msg + i / 100000);}}}}//调用new Thread() {@Overridepublic void run() {super.run();showDo1("线程一");}}.start();new Thread() {@Overridepublic void run() {super.run();showDo("线程二");showDo1("线程二");}}.start();
结果:
由上可得,多个同步锁,只有竞争同一个同步锁才会需要等待,不是竞争同一个锁的代码块互不影响。
- synchronized不能修饰构造函数
- 定义接口方法时不能使用synchronized
- synchronized(this)锁的是当前对象,当前有几个对象,this就有多少份
- synchronized(XX.class)这个与当前对象无关,只要锁是XX.class的都会被同步
- 如果同一个类中有多个方法使用了同步锁synchronized(this)或者多个方法被synchronized修饰,则多个线程访问该类中同步方法时,每次只能访问一个,其它的被阻塞。如:
public synchronized void A(){......
}
public synchronized void B(){......
}
有两个线程分别访问同一个对象T的A方法和B方法,则同时只能有一个方法被其中一个线程访问,另一个线程处于阻塞状态,因为方法A和B持有同一个对象锁,synchronized(this)也是类似的情况。
- 同一个类中有多个方法使用了同步锁synchronized修饰,且这些类是静态的,因为静态方法是属于类的,而不是属于某个对象的,所以它与synchronized(XX.class)类似。
public synchronized static void method() {// todo
}
- 每个对象只有一个锁(lock)与之相关联,谁拿到这个锁谁就可以运行它所控制的那段代码。
- 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。
这篇关于【并发】android中的synchronized的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!