黑马程序员_java中的同步

来源:互联网 发布:起点客户端数据 编辑:程序博客网 时间:2024/05/19 10:08

------- android培训、java培训、期待与您交流! ----------

问题引出,一个简单的出票程序:

class Ticket implements Runnable//extends Thread{private  int tick = 100;public void run(){while(true){if(tick>0){System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);}}}}class  TicketDemo{public static void main(String[] args) {Ticket t = new Ticket();Thread t1 = new Thread(t);//创建了一个线程;Thread t2 = new Thread(t);//创建了一个线程;Thread t3 = new Thread(t);//创建了一个线程;Thread t4 = new Thread(t);//创建了一个线程;t1.start();t2.start();t3.start();t4.start();}}
该程序一个实例化的对象,创建了四个线程;模拟4个出票口共享一个100张票的数据库;运行结果出现-1,-2.。

原因分析:这个出票程序中,线程1启动后,还没有执行出票命令,线程2参与进来,以此类推,等所有线程都启动后,才开始执行出票。导致出票时,并没有执行判断tick是否大于0.导致出现安全问题。

由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问。这个机制就是同步。此时就要加入同步来解决,以保证对于多条操作共享的数据的语句只能在某一时间让一个线程执行完。其它线程此时不能执行;

同步代码格式:

synchronized(对象)

原程序修改如下:

class Ticket implements Runnable//extends Thread{private  int tick = 4000;Object obj=new Object();public void run(){while(true){synchronized(obj){if(tick>0){try{Thread.sleep(10);}catch(Exception e){}System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);}}}}}

运行后,问题解决。

需要明确的几个问题:

       1)  synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。如果 再细的分类,synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。
        2)  无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。
        3)  每个对象只有一个锁(lock)与之相关联。
        4)  实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。

 所以,在开发中用同步控制时,应当注意以下几点:

1)明确哪些代码是共享代码;

2)明确共享数据;

3)明确多线程运行代码中哪些语句是共享数据的。

 

 

0 0
原创粉丝点击