多线程

关键字: 多线程

经常会遇到一个这样的问题:如何实现 判断一个内存对象如Vector 是否有数据,如果有数据 就及时的 读取出来?
常用的普通方法是 用一个 while()循环 这个 Vector是否有数据,如果有数据 才读取。 但是  这种方法 占用的资源
多,效率不高。


以下教你 如何 用JAVA的 wait(),notify(),notifyAll(),结合多线程来实现 上面的问题。java对象都会有一个wait(),
notify(),notifyAll(),3个方法,是因为JAVA在设计时就已经考虑了 对象的同步问题, 我们要上面的问题 也就是 如何
同步Vector的问题。 java的同步机制 就 需要用到一个 概念 (对象锁),即用 synchronized 来实现同步。
底下就一个详细的好例子,:::,

package com.netphonebook.base.thread;

import java.util.Vector;

public class TestWaitAndNotify {
 public Vector v;

 public TestWaitAndNotify() {
  v = new Vector();

 }

 public static void main(String[] args) {
  TestWaitAndNotify test = new TestWaitAndNotify();

  Thread t1 = new Thread(new addThread(test.v),"add's thread");
  Thread t2 = new Thread(new deleteThread(test.v),"delte's thread");

  t1.start();
  t2.start();

 }

}

class addThread implements Runnable {

 private Vector v;

 public addThread(Vector v) {
  this.v = v;
 }

 public void run() {
  int i = 10;
  while (i-- > 0) {
   synchronized (this.v) {
    if (this.v.size() == 0) {
     this.v.addElement(new String("测试"));
     System.out.println("线程:"+Thread.currentThread().getName()+"   已经添加完毕。");
     try {
      Thread.sleep(100);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     this.v.notifyAll();
    } else {
     try {
      System.out.println("线程:"+Thread.currentThread().getName()+"   开始等待。。。");
      this.v.wait();
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
    }

   }
  }

 }

}

class deleteThread implements Runnable {

 private Vector v;

 public deleteThread(Vector v) {
  this.v = v;
 }

 public void run() {
  int i = 10;
  while (i-- > 0) {
   synchronized (this.v) {
    if (this.v.size() != 0) {
     this.v.removeAllElements();
     System.out.println("线程:"+Thread.currentThread().getName()+"   已经删除完毕。");
     try {
      Thread.sleep(100);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     this.v.notifyAll();
    } else {
     try {
      System.out.println("线程:"+Thread.currentThread().getName()+"   开始等待。。。");
      this.v.wait();
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
    }

   }

  }
 }

}

 

继续深入研究多线程。。。
我把今天的成果给大家介绍介绍,相信大家以后要是有用得到多线程 处理数据同步的时候,肯定会用的上的。。。
之前我们说到用 synchronized关键字可以 结合 对象Object的wait(),notify(),可以实现数据的同步。
但是这种同步只能针对于synchronized(){...}模块里面的。如果要实现一个 流程同步 那么单单靠synchronized(){}
是不足实现的。什么叫流程同步,就比如:银行取款,查询,存款,这是一个必须要独立运行的,也就是说,3个
操作是要一起完成的。或者象 数据库的同步,先删除再插入 两个操作要绑定一起运行。

下面举个简单的例子:

本例中 我们这儿编写一个新的Account类,ATM类来模拟自动提款机,通过一个ATMTester的类,生成10个ATM线程,
同时对John账户进行查询、提款和存款操作(备注:某个银行帐户account,在ATM操作时,我们不排除在同一个时刻
可能会有相同的银行帐号在进行取款,存款,查询
3个操作。)

本人思路:
1、多线程操作同一个数据时,若要实现数据的同步,就需要用到一个对象锁机制,object.wait(),object.notify()
   注意,这个对象,应该叫实例(new Object()),其中wait(),notify()要对应,不能instance1.wait(),instance2.notify(),
   这样子肯定报错。也就是实例A等待了,就必须要用实例A亲自去唤醒。(这个是初学者经常犯的错误),理解了
   第一点,我们再看第二点。

2、封装一个对象lock,把这个对象当成锁,这样就可以把这个锁 当成工具,再来锁别的数据。这个锁主要有两个方法,
   一个是上锁,一个解锁。拥有这个所的对象实例A,一旦上锁了,其他别的线程是不能够访问到这个对象实例A,只有
   开了锁,其他的线程才有机会去访问这个对象实例A。

3、我们封装的这个对象lock,可以用来锁住当前登陆的银行帐户,当用户一登陆就上锁,只有等帐户退出了才解锁。这样
   肯定可以确保不同线程的数据同步。


首先,我们来看看如何封装这个对象锁,当成工具锁。
 
package com.netphonebook.base.thread.sync;

public class MyLock {
 private Thread currentT = null;
  
 
//上锁方法
 public synchronized void lock(){
  
  System.out.println("******************上锁(开始)*******************"+Thread.currentThread().getName());
  System.out.println("进入的当前线程:"+Thread.currentThread().getName());
  System.out.println("当前忙碌线程:"+currentT);
  if(currentT == null){
   currentT = Thread.currentThread();
  }
  
  
  
  if(currentT != Thread.currentThread()){
   try {
    System.out.println("忙的线程:"+ currentT.getName()+" 现在是  " + Thread.currentThread().getName() +" 等待。");
    wait();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
  

//重点,上段代码是一个等待堵塞过程,一旦这个堵塞过程结束了,也就是有线程给notify唤醒了,所以把这个当前个唤醒的
//线程又赋值给currentT
  if(currentT == null){
   currentT = Thread.currentThread();
  }
  System.out.println("******************上锁(结束)*******************"+Thread.currentThread().getName());
 }
 

//解锁方法
 public synchronized void unLock(){
  System.out.println("----------开始解锁----------"+Thread.currentThread().getName());
  System.out.println("当前忙碌线程:"+currentT);
  if(currentT == Thread.currentThread()){
   currentT = null;
   notify();
  }
  System.out.println("----------结束解锁----------"+Thread.currentThread().getName());
 }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值