android synchronized 方法,【并发】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(){

@Override

public void run() {

super.run();

showDo("线程一");

}

}.start();

new Thread(){

@Override

public void run() {

super.run();

showDo("线程二");

}

}.start();

结果:

350bd9963162

image.png

未加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);

}

}

}

结果

350bd9963162

image.png

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() {

@Override

public void run() {

super.run();

showDo1("线程一");

}

}.start();

new Thread() {

@Override

public void run() {

super.run();

showDo("线程二");

showDo1("线程二");

}

}.start();

结果:

350bd9963162

image.png

由上可得,多个同步锁,只有竞争同一个同步锁才会需要等待,不是竞争同一个锁的代码块互不影响。

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)与之相关联,谁拿到这个锁谁就可以运行它所控制的那段代码。

实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值