又是忙碌的一天,Java结束了复习,老师也开始讲新的课程了。下午下课,很任性的没有去吃饭,后来与老师讨论时就说到了线程同步的问题。有了点自己的感触,想给大家分享一下,希望能让像我一样的程序员能有所收获。
我们都知道,多线程编程为程序开发带来了很多的便利,但是也带来了一些问题,这些问题时在程序开发过程中必须进行处理的。这些问题的核心是,如果多个线程同时访问一个资源,如变量、文件等,如何保证访问安全?
举个例子,假设有两个线程:线程A和线程B,并且程序为这两个线程开辟了一个公共的内存空间,情况则是线程B写一次,线程A读一次。那么则会出现如下几种情况:
1.在某个时候线程B运行速度比较快,在线程A未读取上一个数据之前,B就写了第二次数据,造成数据遗漏。
2.在某个时候线程A运行速度比较快,它读完一次数据之后,线程B还没来得及写,线程A又来读第二次。结果线程A读不到数据,导致运行出错。 3.线程B正在写数据时,线程A也来读取数据,这时可能线程B还没将数据写完,线程A将数据读走,导致程序出错。 接下来,就让我用代码来演示同步产生的错误的情况: 利用线程来模拟售票系统: 票类:public class Tickets {
public int total;//在票这个类中定义票的数量
public Tickets(int total){//初始化
this.total=total;
}
public void action(String threadName){
System.out.println(threadName+"卖票之前"+total);
total--;
System.out.println(threadName+"卖票之后"+total);
}
}
线程类:
public class TicketsThread extends Thread{
private Tickets tickets;//票的对象
public TicketsThread(Tickets tickets) {//初始化票的对象
this.tickets=tickets;
}
@Override
public void run() {
while(true){
if(tickets.total<=1){
break;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tickets.action(Thread.currentThread().getName());
}
}
}
测试类:
public class Test {通过测试类的运行结果为:
public static void main(String[] args) {
Tickets t=new Tickets(10);
TicketsThread tt1=new TicketsThread(t);
tt1.start();
TicketsThread tt2=new TicketsThread(t);
tt2.start();
}
}
public class Tickets {
public int total;//在票这个类中定义票的数量
public Tickets(int total){//初始化
this.total=total;
}
public synchronized void action(String threadName){//定义同步化,即线程A访问时,线程B必须等待;线程B访问时,线程A必须等待
System.out.println(threadName+"卖票之前"+total);
total--;
System.out.println(threadName+"卖票之后"+total);
}
}
再让我们来看看输出的结果: