写在前面:在做徐boss布置的并行计算作业中,遇到了一些坑,同时也有几个同学问我类似的问题,于是想写篇东西记一下。
一、Synchronized关键字的用法
synchronized关键字有多种用法,这里介绍用于同步方法以及同步代码块。
1.同步方法
synchronized关键字可用于方法的声明中,用于同步某个方法,加了synchronized关键字的方法相当于一个临界区,同一个
对象的
同一个synchronized方法同一时间只允许一个线程访问。
public synchronized void method(){}
由于徐boss说我们是唯一一届有并行计算课程的(具体忘了,反正就是那个么意思)那我就用徐boss布置的作业作为例子使用一下啦,不用担心被学弟学妹们看到我的辣鸡代码。思考了一下,徐boss作业好像不能用这种方式实现。。算了强行实现一波吧
下面用一个例子来演示synchronized同步方法的使用:
/**
* Created by Charlie Mu on 2018/5/16.
*/
public class AnotherSaleTicket {
public static void main(String[] args)
{
int flag=0;
for(int j=0;j<100;j++)//为什么加循环?因为由于是随机的买票,那么如何验证程序是否正确呢 那就多运行几次看看会不会出错咯
{
Ticket ticket=new Ticket();
AnotherBoxOffice windows1=new AnotherBoxOffice(1,ticket);
AnotherBoxOffice windows2=new AnotherBoxOffice(2,ticket);
AnotherBoxOffice windows3=new AnotherBoxOffice(3,ticket);
AnotherBoxOffice windows4=new AnotherBoxOffice(4,ticket);
windows1.start();
windows2.start();
windows3.start();
windows4.start();
try
{
windows1.join();
windows2.join();
windows3.join();
windows4.join();
}
catch (InterruptedException e)
{
System.out.println("Interrupt...");
}
if(ticket.counter==30)
{
flag=1;
}
else
{
flag=0;
break;
}
}
if(flag==1)
{
System.out.println("Perfect!");
}
else
{
System.out.println("There is something wrong...");
}
}
}
class Ticket
{
private int []ticket;
public int counter=0;//用于测试的一个统计值
public Ticket()
{
ticket=new int[30];
for(int i=0;i<30;i++)//0代表票还没卖出去
{
ticket[i]=0;
}
}
public synchronized void saleTicket(int i,int threadNumber)//同步saleTicket方法
{
if(ticket[i]==0)
{
ticket[i]=threadNumber;
//System.out.println("Window "+threadNumber+" Sale the ticket :"+i+". Thread: "+Thread.currentThread().getName());//用于输出卖票情况
counter++;//统计值加一
}
}
public boolean saleout()//判断票是否已经卖完
{
for(int i=0;i<30;i++)
{
if(ticket[i]==0)
{
return false;
}
}
return true;
}
}