Java 线程编程中的同步、重复、定时

来源:互联网 发布:windows闹钟软件 编辑:程序博客网 时间:2024/04/28 11:42

(一)线程同步

实现生产者消费者问题来说明线程问题,举例如下所示:

 

 其中需要注意的是java多线程之 wait(),notify(),notifyAll()方法:

wait(),notify(),notifyAll()不属于Thread类,而是属于Object基础类,也就是说每个对像都有wait(),notify(),notifyAll()
的功能.因为都个对像都有锁,锁是每个对像的基础,当然操作锁的方法也是最基础了.
先看java doc怎么说:
 wait导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。当前的线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行.

 notify唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程。此方法只应由作为此对象监视器的所有者的线程来调用.

"当前的线程必须拥有此对象监视器"与"此方法只应由作为此对象监视器的所有者的线程来调用"说明wait方法与notify方法必须在同步块内执行,即synchronized(obj之内).

调用对像wait方法后,当前线程释放对像锁,进入等待状态.直到其他线程(也只能是其他线程)通过notify 方法,或 notifyAll.该线程重新获得对像锁.
继续执行,记得线程必须重新获得对像锁才能继续执行.因为synchronized代码块内没有锁是寸步不能走的,可以写成

 

(二)线程的定时执行:

      会用到java.util.Calendar和java.util.timer类,

1.java.util.Calendar用来设定时间,java.util.timer定时执行

Calendar c = Calendar.getInstance();得到calendar类,

c.setTime(Date)设定时间,或是c.set(year,month,day,hour,m,s);注意,显示的月份比真实事件多一个月,我们设定时要比真实时间剪掉一个月如:现在是5月,我们定时的时候要写4

2.

Timer time = new Timer();
  Integer a = new Integer(0) ;
  MyTime t = new MyTime();//继承自TimerTask类,实现了run()方法,其中是日期的比较
  //一秒后执行,每5秒执行一次
  time.schedule(t, 1000,5000);

 

3.time定时器的关闭

如果你使用的是JDK 5+,还有一个scheduleAtFixedRate模式可以用,在这个模式下,Timer会尽量的让任务在一个固定的频率下运行,举例说明:在上面的例子中,我们想让MyTask在1秒钟后,每两秒钟执行一次,但是因为java不是实时的(其实java实时性很差.....),所以,我们在上个程序中表达的原义并不能够严格执行.如果我们调用的是scheduleAtFixedRate,那么,Timer会尽量让你的Task执行的频率保持在2秒一次.运行上面的程序,假设使用的是scheduleAtFixedRate,那么下面的场景就是可能的:1秒钟后,MyTask 执行一次,因为系统繁忙,之后的2.5秒后MyTask 才得以执行第二次,然后,Timer记下了这个延迟,并尝试在下一个任务的时候弥补这个延迟,那么,1.5秒后,MyTask 将执行的三次."以固定的频率而不是固定的延迟时间去执行一个任务"

 

 

果然很方便吧^_^

 

 

下面给出一个复杂点的例子,其中告诉大家怎么退出单个TimerTask,怎么退出所有Task

原创粉丝点击