同步:用关键字synchronized给针对共享资源的操作(方法或代码块)加锁,这把锁就叫作互斥锁。所以有两种加锁方式,一种是同步方法,一种是同步代码块。如图:
特别提示:锁住的不是方法,也不是代码块,而是对象,并且是同一个对象。也就是说一个线程正在调用该对象的同步方法,如果还没有执行完成,那么另一个线程就无法调用该对象的所有同步方法或代码块(会阻塞),当然没有加synchronized关键字的方法或代码块不会被锁住。
示例代码1:
class ShareObj{
String[] colors1={"red","orange","yellow", "green",
"blue","indigo","purple","black","white"};
String[] colors2={"红色","橙色","黄色", "绿色",
"蓝色","靛色","紫色","黑色","白色"};
synchronized void printColor(String thName){
if(thName.equals("color")){
for(int i=0;i
如果printColor方法没有加synchronized关键字,运行结果如下:
红色
red
orange
yellow
橙色
green
黄色
绿色
blue
蓝色
indigo
purple
靛色
紫色
black
white
黑色
白色
如果我们要求一个线程在调用printColor的时候,其它线程不能调用,我们就可以在printColor前面加上synchronized关键字
运行结果如下所示:
红色
橙色
黄色
绿色
蓝色
靛色
紫色
黑色
白色
red
orange
yellow
green
blue
indigo
purple
black
white
public class Bank {
private int balance =0;//账户余额
//存钱
public void addMoney(int money){
System.out.println("======存钱start=======");
balance +=money;
System.out.println(System.currentTimeMillis()+"存进:"+money);
System.out.println("账户余额:"+balance);
System.out.println("======存钱end=======");
}
//取钱
public void subMoney(int money){
System.out.println("======取钱start=======");
if(balance-money < 0){
System.out.println("余额不足");
System.out.println("======取钱end=======");
return;
}
balance -=money;
System.out.println(+System.currentTimeMillis()+"取出:"+money);
System.out.println("账户余额:"+balance);
System.out.println("======取钱end=======");
}
}
public class SyncBankTest {
public static void main(String[] args) {
final Bank bank=new Bank();
Thread tadd=new Thread(new Runnable() {
public void run() {
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
bank.addMoney(100);
}
}
});
Thread tsub = new Thread(new Runnable() {
public void run() {
while(true){
bank.subMoney(100);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
tsub.start();
tadd.start();
}
}
======存钱start=======
1505238241890存进:100
账户余额:100
======存钱end=======
======取钱start=======
1505238242890取出:100
账户余额:0
======存钱start=======
======取钱end=======
1505238242890存进:100
账户余额:100
======存钱end=======
======取钱start=======
1505238243890取出:100
账户余额:0
======取钱end=======
======存钱start=======
1505238243890存进:100
账户余额:100
======存钱end=======
如果在存钱和取钱的方法上加上synchronized关键字,运行结果如下所示:
======取钱start=======
余额不足
======取钱end=======
======存钱start=======
1505238048821存进:100
账户余额:100
======存钱end=======
======取钱start=======
1505238048834取出:100
账户余额:0
======取钱end=======
======存钱start=======
1505238049821存进:100
账户余额:100
======存钱end=======
======取钱start=======
1505238049834取出:100
账户余额:0
======取钱end=======
======存钱start=======
1505238050821存进:100
账户余额:100
======存钱end=======
======取钱start=======
1505238050834取出:100
账户余额:0
======取钱end=======
示例代码3:
class SyncCla {
public synchronized void test() {
System.out.println("test开始..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test结束..");
}
}
class MyThread extends Thread {
public void run() {
SyncCla sync = new SyncCla();
sync.test();
}
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
Thread thread = new MyThread();
thread.start();
}
}
}
test开始..
test开始..
test开始..
test结束..
test结束..
test结束..
说明synchronized关键字是对同一对象加锁!!!!切记切记!