多进程的同步控制是避免数据的混乱,尤其是对共享数据
解决的办法:多进程共享的数据只允许同一时刻一个线程处于操作之中(synchronized)
几个重要的概念:
临界资源(同步资源):多线程共享的资源或数据
临界区(临界代码):每个线程中访问临界资源的那一段代码,简单的说就是在一个时刻只能被一个线程访问的资源
synchronized的用法:可以把synchronized想象成一把锁,专门锁住一个线程正在访问临界资源的临界区。访问结束就把锁给下一个线程
格式一:同步语句
Synchronized (对象)
{
临界代码段
}
格式二:同步方法
public synchronized 返回类型 方法名()
{
方法体
}
或者
public 返回类型 方法名()
{
synchronized(this)
{
方法体
}
}
不加synchronized的银行取款应用程序
package practice4;
public class Mbank {
private static int sum=2000;
public static void take(int k){
int temp=sum;
temp-=k;
try {
Thread.sleep((int)(1000*Math.random()));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sum=temp;
System.out.println("sum="+sum);
}
}
public class Customer extends Thread{
public void run(){
for(int i=1;i<=4;i++){
Mbank.take(100);
}
}
}
package practice4;
public class App11_6 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Customer c1=new Customer();
Customer c2=new Customer();
c1.start();
c2.start();
}
}
运行结果:
sum=1900
sum=1900
sum=1800
sum=1700
sum=1600
sum=1800
sum=1700
sum=1600
运行结果显然不对,数据已经混乱
加了synchronized的银行取款应用程序
package practice4;
public class Mbank {
private static int sum=2000;
public synchronized static void take(int k){
int temp=sum;
temp-=k;
try {
Thread.sleep((int)(1000*Math.random()));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sum=temp;
System.out.println("sum="+sum);
}
}
public class Customer extends Thread{
public void run(){
for(int i=1;i<=4;i++){
Mbank.take(100);
}
}
}
public class App11_6 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Customer c1=new Customer();
Customer c2=new Customer();
c1.start();
c2.start();
}
}
运行结果:
sum=1900
sum=1800
sum=1700
sum=1600
sum=1500
sum=1400
sum=1300
sum=1200