在JAVA平台 实现异步调用的角色有如下三个角色:调用者 提货单 真实数据一个调用者在调用耗时 *** 作 不能立即返回数据时 先返回一个提货单 然后在过一断时间后凭提货单来获取真正的数据 去蛋糕店买蛋糕 不需要等蛋糕做出来(假设现做要很长时间) 只需要领个提货单就可以了(去干别的事情) 等到蛋糕做好了 再拿提货单取蛋糕就可以了 public class Main { public static void main(String[] args) {
System out println( main BEGIN );
Host host = new Host();
Data data = host request( A );
Data data = host request( B );
Data data = host request( C );
System out println( main otherJob BEGIN );
try {
Thread sleep( );
} catch (InterruptedException e) {
}
System out println( main otherJob END );
System out println( data = + data getContent());
System out println( data = + data getContent());
System out println( data = + data getContent());
System out println( main END );
}
}
这里的main类就相当于 顾客 host就相当于 蛋糕店 顾客向 蛋糕店 定蛋糕就相当于 发请求request 返回的数据data是FutureData的实例 就相当于提货单 而不是真正的 蛋糕 在过一段时间后(sleep一段时间后) 调用data getContent() 也就是拿提货单获取执行结果
下面来看一下 顾客定蛋糕后 蛋糕店做了什么
public class Host {
public Data request(final int count final char c) {
System out println( request( + count + + c + ) BEGIN );
// ( ) 建立FutureData的实体
final FutureData future = new FutureData();
// ( ) 为了建立RealData的实体 启动新的线程
new Thread() {
public void run() {
//在匿名内部类中使用count future c
RealData realdata = new RealData(count c);
future setRealData(realdata);
}
} start();
System out println( request( + count + + c + ) END );
// ( ) 取回FutureData实体 作为传回值
return future;
}
}
host( 蛋糕店 )在接到请求后 先生成了 提货单 FutureData的实例future 然后命令 蛋糕师傅 RealData去做蛋糕 realdata相当于起个线程去做蛋糕了 然后host返回给顾客的仅仅是 提货单 future 而不是蛋糕 当蛋糕做好后 蛋糕师傅才能给对应的 提货单 蛋糕 也就是future setRealData(realdata)
下面来看看蛋糕师傅是怎么做蛋糕的
建立一个字符串 包含count个c字符 为了表现出犯法需要花费一些时间 使用了sleep
public class RealData implements Data { private final String content;
public RealData(int count char c) {
System out println( making RealData( + count + + c + ) BEGIN );
char[] buffer = new char[count];
for (int i = ; i < count; i++) {
buffer[i] = c;
try {
Thread sleep( );
} catch (InterruptedException e) {
}
}
System out println( making RealData( + count + + c + ) END );
ntent = new String(buffer);
}
public String getContent() {
return content;
}
}
现在来看看 提货单 future是怎么与蛋糕 content 对应的:
public class FutureData implements Data { private RealData realdata = null;
private boolean ready = false;
public synchronized void setRealData(RealData realdata) {
if (ready) {
return; // 防止setRealData被调用两次以上
}
this realdata = realdata;
this ready = true;
notifyAll();
}
public synchronized String getContent() {
while (!ready) {
try {
wait();
} catch (InterruptedException e) {
}
}
return realdata getContent();
}
}
顾客做完自己的事情后 会拿着自己的 提货单 来取蛋糕
System out println( data = + data getContent());
这时候如果蛋糕没做好 就只好等了
while (!ready) { try {
wait();
} catch (InterruptedException e) {
}
//等做好后才能取到
return realdata getContent();
程序分析
对于每个请求 host都会生成一个线程 这个线程负责生成顾客需要的 蛋糕 在等待一段时间以后 如果蛋糕还没有做好 顾客还必须等待 直到 蛋糕被做好 也就是
future setRealData(realdata); 执行以后 顾客才能拿走蛋糕
每个线程只是专门负责制作特定顾客所需要的 蛋糕 也就是顾客A对应着蛋糕师傅A 顾客B对应着蛋糕师傅B 即使顾客B的蛋糕被先做好了 顾客A也只能等待蛋糕师傅A把蛋糕做好 换句话说 顾客之间没有竞争关系
lishixinzhi/Article/program/Java/gj/201311/27425
修改数据库可以使用数据库本身的计划任务(job),这种方式最好。
第二种是使用程序来做如java的timer和timetask。保证在项目启动的时候启动该计划任务。
public static void main(String[] args) {//定时任务
final Timer timer = new Timer();
// 指定任务在星期四中午12:00执行
Calendar calendar = CalendargetInstance();
calendarset(CalendarDAY_OF_WEEK, CalendarTUESDAY);
calendarset(CalendarHOUR_OF_DAY, 12);
calendarset(CalendarMINUTE, 00);
calendarset(CalendarSECOND, 0);
javautilDate time = calendargetTime();
timerschedule(new TimerTask() {
public void run() {
// 你要执行的 *** 作
try{
} catch (Exception e) {
// 出现异常的 *** 作:如取消计划任务
timercancel();
}
}
},time);
}
图形界面 awt的 东西在tomcat可能会受限制。
catalinabat 或者 catalinash 里面 改成
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djavaawtheadless=true "
“-Djavaawtheadless=true” 这个是关键。加上试试。
以上就是关于Java多线程实现异步调用全部的内容,包括:Java多线程实现异步调用、java 定时的问题,我现在想实现的是每个月的第四个工作日中午十二点去扫描数据库,修改一个字段的状态、在eclipse中使用java的PrinterJob job = PrinterJob.getPrinterJob();开发环境中,可以取得打印机等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)