Java CookBook(二)
通过HTTP连接访问资源
URLConnection封装任何对URL连接的基本功能,HttpURLConnection基于HTTP的连接扩展URLConnection。
Step1.创建URL对象。URL(String rul) throws MalformedURLException
Step2.URL对象调用openConnection(),并将其返回的引用强制转换成HttpURLConnection。
Step3.HttpURLConnection对象调用getContentType()获取资源的内容类型,调用getContentLength()获取资源的内容长度,调用Map<String,List<String>> getHeaderFields()返回包含所有标题字段的键值对。
Step4.HttpURLConnection对象调用getInputStream()获取资源的输入流。读取这个流就能够下载资源。
applet和servlet
applet是一种小程序,它动态地通过Web发送,并在浏览器中运行。servlet是在服务器端运行的小程序。applet有两种:直接基于java.applet定义的Applet类;基于Swing的applet是现在最流行的。
多线程
虽然多线程增加了编程的复杂性,但现在的趋势是使用更多的线程。
基于任务的多进程并不在Java的控制之下。
对于涉及到I/O操作时,尤其适用于多线程。
在事件模型中,如果某个事件持续时间较长的动作,它必须由独立的线程执行,否则可能得不到及时地处理,显得应用程序缓慢,也可能事件丢失。
要创建一个新的线程,要么扩展Thread类,要么实现Runnable接口。
Thread(ThreadGroup thrdGroup,Runnable thrdObj,String thrdName)
Thread(Runnable thrdObj,String thrdName)
Thread(Runnable thrdObj)
Thread(String thrdName)
在开发、测试和调度中线程名thrdName是很有用的。
Long tid=Thread.currentThread().getId();
线程ID可以利用,当某个线程被终止时,新的线程可以被赋予旧线程的ID。
join()无限期地等待线程结束,也可以指定最长等待时间。
Final void join(long milliseconds) throws InterruptedException
Final void join(long milliseconds,int nanoseconds) throws InterruptedException
synchronized(objref){ } //同步块把对象 objref锁住
synchronized returnType methodName(arg-list){ }同步方法每次只能有一个对象调用它。
if(Character.isWhitespace(msg.charAt(i)))
new Thread(this).start();
线程调用调用wait()放弃对对象的控制,一直等待notify()通知。notify()会恢复某个正在等待的线程,notifyAll() 会恢复所有正在等待的线程。
同sleep()一样,wait()是无限期等待,我们也可为其设置时限:
fianl void wait(long milliseconds) throws InterruptedException
Final void wait(long milliseconds,int nanoseconds) throws InterruptedException
不推荐使用suspend(),resume()和stop()方法。
Final void setDaemon(boolean how) how为true时,把线程设为守护状态;为false时,设为用户状态。必须在启动线程之前调用。
Final boolean isDaemon()
一个线程想中断另一个线程可以对其调用interrupt()。判断线程是否被中断可调用interrupted()。
当线程因sleep(),wait(),join()而暂停时,对其调用interrupt()会抛出InterruptedException。
Static void yield()可使另外的线程,包括优先级更低的线程获取CPU访问权。
ThreadGroup(String name)
Thread(ThreadGroup thrdGroup,Runnable thrdObj,String thrdName)
ThreadGroup中的方法:
int activeCount() 组中活跃的线程数量
int enumerate(Thread[] thrds) 获得组中线程列表
final void interrupt()中断组中所有线程
利用信号量
package Nine; /** * java并发实用工具对原始多线程和同步方法的补充而不是替换,这些原始方法是简练且高效的 */ import java.io.FileWriter; import java.io.IOException; import java.util.concurrent.Semaphore; public class SemDemo { public static void main(String[] args) { Semaphore sem = new Semaphore(1, true); //信号量设为1则为互斥锁 FileWriter fw; try { fw = new FileWriter("Log.dat"); } catch (IOException exe) { System.out.println("Error writing file."); return; } Thread thrA=new Thread(new SyncOutput(sem,fw,"Transfer Complete")); Thread thrB=new Thread(new SyncOutput(sem,fw,"Connection lost!")); thrA.start(); thrB.start(); try{ thrA.join(); thrB.join(); fw.close(); }catch (IOException exe) { System.out.println("Error Closing file."); } catch (InterruptedException exec) { System.out.println("Intrerupted"); } } } class SyncOutput implements Runnable { Semaphore sem; String msg; FileWriter fw; SyncOutput(Semaphore s, FileWriter f, String m) { sem = s; msg = m; fw = f; } public void run() { try { sem.acquire(); // 申请获得通行证 for (int i = 0; i < msg.length(); i++) { fw.write(msg.charAt(i)); Thread.sleep(10); // 故意给其他线程运行的机会,但由于设置为互斥锁,其他线程是得不到运行机会的 } fw.write("\n"); } catch (IOException exe) { System.out.println("Error writing file."); } catch (InterruptedException exec) { System.out.println(exec); } sem.release(); // 释放通行证 } } /* * 由于设置了互斥锁,线程A在执行的过程中线程B不能打断,所以Log.dat文件中的内容是: * Transfer Complete * Connection lost! * 如果把“sem.acquire();”注释掉,则线程AB交替执行,Log.dat文件内容很混乱: * TCroannnsefcetri oCno mlpolsett!e * */
从线程返回一个值
package Nine; import java.io.FileWriter; import java.io.IOException; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class TheRetVal { public static void main(String[] args){ ExecutorService es=Executors.newFixedThreadPool(3); //使用纯种池来执行任务,池中有三个线程。线程可以重复使用,即线程执行完一个途程后可以去执行另外一个线程。线程的利用比创建多个独立的线程更有效率 Future<Double> f; Future<Integer> f2; Future<Boolean> f3; Double nums[]={1.0,2.2,3.5,7.25}; f=es.submit(new Avg(nums)); f2=es.submit(new Factorial(4)); f3=es.submit(new WriteField("test.dat","this is a test")); try{ System.out.println(f.get()); System.out.println(f2.get()); System.out.println(f3.get()); }catch(ExecutionException e){ e.printStackTrace(); }catch(InterruptedException exe){ exe.printStackTrace(); } es.shutdown(); } } class Avg implements Callable<Double>{ Double[] data; Avg(Double[] d){ data=d; } @Override public Double call() throws Exception { double sum=0.0; // TODO Auto-generated method stub for(int i=0;i<data.length;i++){ sum+=data[i]; } return sum/data.length; } } class WriteField implements Callable<Boolean>{ String fname; String msg; WriteField(String n,String info){ fname=n; msg=info; } @Override public Boolean call() throws Exception { // TODO Auto-generated method stub FileWriter fw=null; boolean result=true; try{ fw=new FileWriter(fname); fw.write(msg); }catch(IOException e){ result=false; } try{ if(fw!=null)fw.close(); }catch(IOException e){ result=false; } return result; } } class Factorial implements Callable<Integer>{ int num; Factorial(int v){num=v;} @Override public Integer call() throws Exception { // TODO Auto-generated method stub int fact=1; for(int i=2;i<=num;i++){ fact*=i; } return fact; } }
利用反射动态创建对象并调用其方法
package Nine; /** * 利用反射在运行时动态地创建实例并执行其方法,这样在编译时并不需要使用类 */ import java.lang.reflect.Constructor; import java.lang.reflect.Method; class MyClass{ private int count; MyClass(int c){ System.out.println("Executing MyClass(int)."+" Argument is "+c); count=c; } MyClass(){ System.out.println("Executing MyClass()."); count=0; } void setCount(int c){ System.out.println("Executing setCount(int)."+" Argument is "+c); count=c; } int getCount(){ System.out.println("Executing getCount()."); return count; } void showcount(){ System.out.println("Executing showCount()."+" count is "+count); } } public class UseReflection { public static void main(String[] args){ try{ System.out.println("Use Relfection to execute MyClass constructors and methods.\n"); System.out.println("Create an instance of MyClass."); Class c=Class.forName("MyClass"); //通过Class.forName获取一个Class实例(也可获取接口的信息) Constructor constructors[]=c.getConstructors(); //获取类的构造函数信息 Object obj=null; for(Constructor cons:constructors){ Class[] params=cons.getParameterTypes(); //获取构造函数的参数类型 if(params.length==1 && params[0]==int.class){ obj=cons.newInstance(10); //通过反射获取的构造函数创建类的一个实例 break; } } if(obj==null){ System.out.println("Can't create MyClass object."); return; } System.out.println("\nExecute all MyClass methods."); Method[] methods=c.getDeclaredMethods(); //通过反射获取类的方法信息 for(Method meth:methods){ Class[] params=meth.getParameterTypes(); //获取方法的参数信息 if(params.length==1 && params[0]==int.class) meth.invoke(obj, 99); //执行方法 else if(params.length==0){ if(meth.getReturnType()==int.class){ //获取方法的返回类型 Object retval=meth.invoke(obj); //执行方法并获得其返回值 System.out.println("Method returns:"+(Integer)retval); }else if(meth.getReturnType()==void.class){ meth.invoke(obj); } } } }catch(Exception e){ e.printStackTrace(); } } }
安排未来执行的任务
/** * Author: Orisun * Date: Sep 16, 2011 * FileName: SchedTask.java * Function: TimerTask定义要执行的任务,而Timer提供调度安排 */ package Nine; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.Timer; import java.util.TimerTask; public class SchedTask { public static void main(String[] args){ AutoBkUp bkupTask=new AutoBkUp("Mydata.dat","Mydata.bak"); Timer bkTimer=new Timer(); bkTimer.schedule(bkupTask, 2000,2000); //每隔2秒执行一次,每次持续2秒 for(int i=0;i<5;i++){ try{ Thread.sleep(2100); //主线程休息2.1秒,让给AutoBkUp任务去执行 }catch(InterruptedException exe){} if(bkupTask.isSuccessful()){ System.out.println("Last backup was successful."); }else{ System.out.println("Last backup attempt failed."); } } bkTimer.cancel(); //取消调度的任务 } } class AutoBkUp extends TimerTask{ private String bkupName; private String fName; private boolean success; AutoBkUp(String fn,String bk){ fName=fn; bkupName=bk; success=false; } @Override public void run() { // TODO Auto-generated method stub FileInputStream fin=null; FileOutputStream fout=null; int len; byte[] b=new byte[1024]; try{ fin=new FileInputStream(fName); fout=new FileOutputStream(bkupName); for(;;){ len=fin.read(b); if(len==-1)break; else fout.write(b,0,len); } success=true; }catch(IOException e){ success=false; } if(fin!=null){ try{ fin.close(); }catch(IOException e){ success=false; } } if(fout!=null){ try{ fout.close(); }catch(IOException e){ success=false; } } fin=null; fout=null; } boolean isSuccessful(){ return success; } }
本文来自博客园,作者:高性能golang,转载请注明原文链接:https://www.cnblogs.com/zhangchaoyang/articles/2181403.html