java 方法 执行超时处理

java 方法 执行超时处理,第1张

java 15以上的Future类可以执行超时处理。

jdk15自带的并发库中Future类中重要方法包括get()和cancel(),get()获取数据对象,如果数据没有加载,就会阻塞直到取到数据,而 cancel()是取消数据加载。另外一个get(timeout) *** 作,表示如果在timeout时间内没有取到就失败返回,而不再阻塞。

代码如下:

import javautilconcurrentCallable;

import javautilconcurrentExecutionException;

import javautilconcurrentExecutorService;

import javautilconcurrentExecutors;

import javautilconcurrentTimeUnit;

import comsuncorbaseimplorbutilclosureFuture;

import comsuncorbaseimplorbutilthreadpoolTimeoutException;

public class ThreadTest {  

  

    public static void main(String[] args) throws InterruptedException,  

            ExecutionException {  

          

        final ExecutorService exec = ExecutorsnewFixedThreadPool(1);  

          

        Callable<String> call = new Callable<String>() {  

            public String call() throws Exception {  

                //开始执行耗时 *** 作  

                Threadsleep(1000  5);  

                return "线程执行完成";  

            }  

        };  

          

        try {  

            Future<String> future = execsubmit(call);  

            String obj = futureget(1000  1, TimeUnitMILLISECONDS); //任务处理超时时间设为 1 秒  

            Systemoutprintln("任务成功返回:" + obj);  

        } catch (TimeoutException ex) {  

            Systemoutprintln("处理超时啦");  

            exprintStackTrace();  

        } catch (Exception e) {  

            Systemoutprintln("处理失败");  

            eprintStackTrace();  

        }  

        // 关闭线程池  

        execshutdown();  

    }  

}

主要内容:

进程是资源分配的最小单位,每个进程都有独立的代码和数据空间,一个进程包含 1 到 n 个线程。线程是 CPU 调度的最小单位,每个线程有独立的运行栈和程序计数器,线程切换开销小。

Java 程序总是从主类的 main 方法开始执行,main 方法就是 Java 程序默认的主线程,而在 main 方法中再创建的线程就是其他线程。在 Java 中,每次程序启动至少启动 2 个线程。一个是 main 线程,一个是垃圾收集线程。每次使用 Java 命令启动一个 Java 程序,就相当于启动一个 JVM 实例,而每个 JVM 实例就是在 *** 作系统中启动的一个进程。

多线程可以通过继承或实现接口的方式创建。

Thread 类是 JDK 中定义的用于控制线程对象的类,该类中封装了线程执行体 run() 方法。需要强调的一点是,线程执行先后与创建顺序无关。

通过 Runnable 方式创建线程相比通过继承 Thread 类创建线程的优势是避免了单继承的局限性。若一个 boy 类继承了 person 类,boy 类就无法通过继承 Thread 类的方式来实现多线程。

使用 Runnable 接口创建线程的过程:先是创建对象实例 MyRunnable,然后将对象 My Runnable 作为 Thread 构造方法的入参,来构造出线程。对于 new Thread(Runnable target) 创建的使用同一入参目标对象的线程,可以共享该入参目标对象 MyRunnable 的成员变量和方法,但 run() 方法中的局部变量相互独立,互不干扰。

上面代码是 new 了三个不同的 My Runnable 对象,如果只想使用同一个对象,可以只 new 一个 MyRunnable 对象给三个 new Thread 使用。

实现 Runnable 接口比继承 Thread 类所具有的优势:

线程有新建、可运行、阻塞、等待、定时等待、死亡 6 种状态。一个具有生命的线程,总是处于这 6 种状态之一。 每个线程可以独立于其他线程运行,也可和其他线程协同运行。线程被创建后,调用 start() 方法启动线程,该线程便从新建态进入就绪状态。

NEW 状态(新建状态) 实例化一个线程之后,并且这个线程没有开始执行,这个时候的状态就是 NEW 状态:

RUNNABLE 状态(就绪状态):

阻塞状态有 3 种:

如果一个线程调用了一个对象的 wait 方法, 那么这个线程就会处于等待状态(waiting 状态)直到另外一个线程调用这个对象的 notify 或者 notifyAll 方法后才会解除这个状态。

run() 里的代码执行完毕后,线程进入终结状态(TERMINATED 状态)。

线程状态有 6 种:新建、可运行、阻塞、等待、定时等待、死亡。

我们看下 join 方法的使用:

运行结果:

我们来看下 yield 方法的使用:

运行结果:

线程与线程之间是无法直接通信的,A 线程无法直接通知 B 线程,Java 中线程之间交换信息是通过共享的内存来实现的,控制共享资源的读写的访问,使得多个线程轮流执行对共享数据的 *** 作,线程之间通信是通过对共享资源上锁或释放锁来实现的。线程排队轮流执行共享资源,这称为线程的同步。

Java 提供了很多同步 *** 作(也就是线程间的通信方式),同步可使用 synchronized 关键字、Object 类的 wait/notifyAll 方法、ReentrantLock 锁、无锁同步 CAS 等方式来实现。

ReentrantLock 是 JDK 内置的一个锁对象,用于线程同步(线程通信),需要用户手动释放锁。

运行结果:

这表明同一时间段只能有 1 个线程执行 work 方法,因为 work 方法里的代码需要获取到锁才能执行,这就实现了多个线程间的通信,线程 0 获取锁,先执行,线程 1 等待,线程 0 释放锁,线程 1 继续执行。

synchronized 是一种语法级别的同步方式,称为内置锁。该锁会在代码执行完毕后由 JVM 释放。

输出结果跟 ReentrantLock 一样。

Java 中的 Object 类默认是所有类的父类,该类拥有 wait、 notify、notifyAll 方法,其他对象会自动继承 Object 类,可调用 Object 类的这些方法实现线程间的通信。

除了可以通过锁的方式来实现通信,还可通过无锁的方式来实现,无锁同 CAS(Compare-and-Swap,比较和交换)的实现,需要有 3 个 *** 作数:内存地址 V,旧的预期值 A,即将要更新的目标值 B,当且仅当内存地址 V 的值与预期值 A 相等时,将内存地址 V 的值修改为目标值 B,否则就什么都不做。

我们通过计算器的案例来演示无锁同步 CAS 的实现方式,非线程安全的计数方式如下:

线程安全的计数方式如下:

运行结果:

线程安全累加的结果才是正确的,非线程安全会出现少计算值的情况。JDK 15 开始,并发包里提供了原子 *** 作的类,AtomicBoolean 用原子方式更新的 boolean 值,AtomicInteger 用原子方式更新 int 值,AtomicLong 用原子方式更新 long 值。 AtomicInteger 和 AtomicLong 还提供了用原子方式将当前值自增 1 或自减 1 的方法,在多线程程序中,诸如 ++i 或 i++ 等运算不具有原子性,是不安全的线程 *** 作之一。 通常我们使用 synchronized 将该 *** 作变成一个原子 *** 作,但 JVM 为此种 *** 作提供了原子 *** 作的同步类 Atomic,使用 AtomicInteger 做自增运算的性能是 ReentantLock 的好几倍。

上面我们都是使用底层的方式实现线程间的通信的,但在实际的开发中,我们应该尽量远离底层结构,使用封装好的 API,例如 JUC 包(javautilconcurrent,又称并发包)下的工具类 CountDownLath、CyclicBarrier、Semaphore,来实现线程通信,协调线程执行。

CountDownLatch 能够实现线程之间的等待,CountDownLatch 用于某一个线程等待若干个其他线程执行完任务之后,它才开始执行。

CountDownLatch 类只提供了一个构造器:

CountDownLatch 类中常用的 3 个方法:

运行结果:

CyclicBarrier 字面意思循环栅栏,通过它可以让一组线程等待至某个状态之后再全部同时执行。当所有等待线程都被释放以后,CyclicBarrier 可以被重复使用,所以有循环之意。

相比 CountDownLatch,CyclicBarrier 可以被循环使用,而且如果遇到线程中断等情况时,可以利用 reset() 方法,重置计数器,CyclicBarrier 会比 CountDownLatch 更加灵活。

CyclicBarrier 提供 2 个构造器:

上面的方法中,参数 parties 指让多少个线程或者任务等待至 barrier 状态;参数 barrierAction 为当这些线程都达到 barrier 状态时会执行的内容。

CyclicBarrier 中最重要的方法 await 方法,它有 2 个重载版本。下面方法用来挂起当前线程,直至所有线程都到达 barrier 状态再同时执行后续任务。

而下面的方法则是让这些线程等待至一定的时间,如果还有线程没有到达 barrier 状态就直接让到达 barrier 的线程执行任务。

运行结果:

CyclicBarrier 用于一组线程互相等待至某个状态,然后这一组线程再同时执行,CountDownLatch 是不能重用的,而 CyclicBarrier 可以重用。

Semaphore 类是一个计数信号量,它可以设定一个阈值,多个线程竞争获取许可信号,执行完任务后归还,超过阈值后,线程申请许可信号时将会被阻塞。Semaphore 可以用来 构建对象池,资源池,比如数据库连接池。

假如在服务器上运行着若干个客户端请求的线程。这些线程需要连接到同一数据库,但任一时刻只能获得一定数目的数据库连接。要怎样才能够有效地将这些固定数目的数据库连接分配给大量的线程呢?

给方法加同步锁,保证同一时刻只能有一个线程去调用此方法,其他所有线程排队等待,但若有 10 个数据库连接,也只有一个能被使用,效率太低。另外一种方法,使用信号量,让信号量许可与数据库可用连接数为相同数量,10 个数据库连接都能被使用,大大提高性能。

上面三个工具类是 JUC 包的核心类,JUC 包的全景图就比较复杂了:

JUC 包(javautilconcurrent)中的高层类(Lock、同步器、阻塞队列、Executor、并发容器)依赖基础类(AQS、非阻塞数据结构、原子变量类),而基础类是通过 CAS 和 volatile 来实现的。我们尽量使用顶层的类,避免使用基础类 CAS 和 volatile 来协调线程的执行。JUC 包其他的内容,在其他的篇章会有相应的讲解。

Future 是一种异步执行的设计模式,类似 ajax 异步请求,不需要同步等待返回结果,可继续执行代码。使 Runnable(无返回值不支持上报异常)或 Callable(有返回值支持上报异常)均可开启线程执行任务。但是如果需要异步获取线程的返回结果,就需要通过 Future 来实现了。

Future 是位于 javautilconcurrent 包下的一个接口,Future 接口封装了取消任务,获取任务结果的方法。

在 Java 中,一般是通过继承 Thread 类或者实现 Runnable 接口来创建多线程, Runnable 接口不能返回结果,JDK 15 之后,Java 提供了 Callable 接口来封装子任务,Callable 接口可以获取返回结果。我们使用线程池提交 Callable 接口任务,将返回 Future 接口添加进 ArrayList 数组,最后遍历 FutureList,实现异步获取返回值。

运行结果:

上面就是异步线程执行的调用过程,实际开发中用得更多的是使用现成的异步框架来实现异步编程,如 RxJava,有兴趣的可以继续去了解,通常异步框架都是结合远程 >

阿珍探出头看了看老徐的屏幕,全部都是绿色的曲线图,好奇地问:“老徐,你看的这是什么?”老徐看的太入神,转过头才发现阿珍,尬尴地笑了笑说:“我就是看看最近的行情。”老徐立马切换了窗口。

阿珍没在意又继续问到:“ Runnable 和 Callable 两个接口我总搞混,这个到底有什么不同?”

面对阿珍的灵魂拷问,老徐淡定自若地说:“ Runnable 是用于提供多线程任务支持的核心接口, Callable 是在Java 15中添加的 Runnable 的改进版本。”

“在聊它们不同之前,我们先分别了解一下两个接口。”老徐一边说着,一边打开了源码:

Runnable 接口是一个函数式接口,它只有一个run()方法,不接受任何参数,也不返回任何值。由于方法签名没有指定 throws 子句,因此无法进一步传播已检查的异常。它适用于我们不使用线程执行结果的情况,例如,异步打印日志:

在上面例中,根据 name 参数把信息记录在日志文件中,没有返回值。我们可以通过 Thread 启动,比如:

我们也可以通过 ExecutorService 启动,比如:

Callable接口也是一个函数式接口,它只有一个call()方法,不接受任何参数,返回一个泛型值V,在方法签名上包含 throws Exception 子句,因此我们可以很容易地进一步传播已检查异常。它适用于我们使用线程执行结果的情况,例如,异步计算阶乘:

在上面例中,根据 n 参数计算它的阶乘,并可以返回计算结结果。我们只能通过 ExecutorService 启动,比如:

call()方法的结果可以通过Future对象获取到,如果在调用Future对象的get()方法时,call()方法出现了异常,异常会被继续传递,比如:

抛出如下异常:

老徐回头看看了阿珍,说:“这回你知道有什么不同了吧!”阿珍一头雾水地说:“信息量有点大呀,可以给我总结一下吗?”“当然可以。”老徐回答。

Runnable和Callable的不同:

有三种:

(1)继承Thread类,重写run函数

创建:

class xx extends Thread{

public void run(){

Threadsleep(1000) //线程休眠1000毫秒,sleep使线程进入Block状态,并释放资源

}}

开启线程:

对象start() //启动线程,run函数运行

(2)实现Runnable接口,重写run函数

开启线程:

Thread t = new Thread(对象) //创建线程对象

tstart()

(3)实现Callable接口,重写call函数

Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。

Callable和Runnable有几点不同:

①Callable规定的方法是call(),而Runnable规定的方法是run()

②Callable的任务执行后可返回值,而Runnable的任务是不能返回值的

③call()方法可抛出异常,而run()方法是不能抛出异常的。

④运行Callable任务可拿到一个Future对象,Future表示异步计算的结果。它提供了检查计算是否完成的方法,以等

待计算的完成,并检索计算的结果通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果

如果是java5的话,那么Java5新增了Callable接口获得线程的返回值,用法如下

package comronniewang;  

  

  

import javautilconcurrentCallable;  

import javautilconcurrentExecutionException;  

import javautilconcurrentExecutorService;  

import javautilconcurrentExecutors;  

import javautilconcurrentFuture;  

  

  

public class GetReturnValueFromCallable {  

  

  

    private static final int SLEEP_MILLS = 3000;  

  

  

    private static final int SECOND_MILLS = 1000;  

  

  

    private static int sleepSeconds = SLEEP_MILLS / SECOND_MILLS;  

  

  

    ExecutorService executorService = ExecutorsnewCachedThreadPool();  

  

  

    / 

      在创建多线程程序的时候,我们常实现Runnable接口,Runnable没有返回值,要想获得返回值,Java5提供了一个新的接口Callable 

     /  

    public static void main(String[] args) {  

  

  

        new GetReturnValueFromCallable()testCallable();  

    }  

  

  

    private void testCallable() {  

  

  

        / 

          Callable需要实现的是call()方法,而不是run()方法,返回值的类型有Callable的类型参数指定, 

          Callable只能由ExecutorServicesubmit() 执行,正常结束后将返回一个future对象 

         /  

        Future<String> future = executorServicesubmit(new Callable<String>() {  

  

  

            public String call() throws Exception {  

  

  

                Threadsleep(SLEEP_MILLS);  

                return "I from callable";  

            }  

        });  

  

  

        while (true) {  

            / 

              获得future对象之前可以使用isDone()方法检测future是否完成,完成后可以调用get()方法获得future的值, 

              如果直接调用get()方法,get()方法将阻塞值线程结束 

             /  

            if (futureisDone()) {  

                try {  

                    Systemoutprintln(futureget());  

                    break;  

                } catch (InterruptedException e) {  

                    // ignored  

                } catch (ExecutionException e) {  

                    // ignored  

                }  

            }  

            else {  

                try {  

                    Systemoutprintln("after " + sleepSeconds-- + " seconds, we will get future");  

                    Threadsleep(SECOND_MILLS);  

                } catch (InterruptedException e) {  

                    // ignored  

                }  

            }  

        }  

    }  

}  

package comronniewang;

import javautilconcurrentCallable;

import javautilconcurrentExecutionException;

import javautilconcurrentExecutorService;

import javautilconcurrentExecutors;

import javautilconcurrentFuture;

public class GetReturnValueFromCallable {

    private static final int SLEEP_MILLS = 3000;

    private static final int SECOND_MILLS = 1000;

    private static int sleepSeconds = SLEEP_MILLS / SECOND_MILLS;

    ExecutorService executorService = ExecutorsnewCachedThreadPool();

    /

      在创建多线程程序的时候,我们常实现Runnable接口,Runnable没有返回值,要想获得返回值,Java5提供了一个新的接口Callable

     /

    public static void main(String[] args) {

        new GetReturnValueFromCallable()testCallable();

    }

    private void testCallable() {

        /

          Callable需要实现的是call()方法,而不是run()方法,返回值的类型有Callable的类型参数指定,

          Callable只能由ExecutorServicesubmit() 执行,正常结束后将返回一个future对象

         /

        Future<String> future = executorServicesubmit(new Callable<String>() {

            public String call() throws Exception {

                Threadsleep(SLEEP_MILLS);

                return "I from callable";

            }

        });

        while (true) {

            /

              获得future对象之前可以使用isDone()方法检测future是否完成,完成后可以调用get()方法获得future的值,

              如果直接调用get()方法,get()方法将阻塞值线程结束

             /

            if (futureisDone()) {

                try {

                    Systemoutprintln(futureget());

                    break;

                } catch (InterruptedException e) {

                    // ignored

                } catch (ExecutionException e) {

                    // ignored

                }

            }

            else {

                try {

                    Systemoutprintln("after " + sleepSeconds-- + " seconds, we will get future");

                    Threadsleep(SECOND_MILLS);

                } catch (InterruptedException e) {

                    // ignored

                }

            }

        }

    }

}

输出结果:

after 3 seconds, we will get future

 after 2 seconds, we will get future

 after 1 seconds, we will get future

 I from callable

Java把不同类型的输入、输出抽象为流stream,分为输入流和输出流,用统一的接口来表示

Java开发环境中提供了包javaio,其中包括一系列的类来实现输入/输出处理

InputStream是所有字节输入流的祖先,而OutputStream是所有字节输出流的祖先

public abstract class InputStream implements Closeable

public abstract class OutputStream implements Closeable, Flushable

具体子类: ByteArrayInputStream, FileInputStream, FilterInputStream, ObjectInputStream,

PipedInputStream, SequenceInputStream, StringBufferInputStream

InputStream

InputStream类是一个抽象类,方法包括:

int read()

int read(byte[])

int read(byte[],int,int)

void close()关闭流

int available()报告流中直接可读的字节数

skip(long)跳过流中指定的字节

OutputStream

OutputStream也是一个抽象类。它的主要方法包括:

void write(int)

void write(byte[])

void write(byte[],int,int)

其中第一个方法的int型的参数对应要写入的字节,后两个方法的参数与InputStream类似。

void close() 关闭输出流

void flush() 强行将写入缓冲区中剩余的数据写入

File file = new File("d:\\FileTestjava");

if (fileexists()) {

try (InputStream is = new FileInputStream(file);) {

byte[] buffer = new byte[8192];

int len = isread(buffer);

while (len > 0) {

Systemoutwrite(buffer, 0, len);

len = isread(buffer);

}

} catch (Exception e) {

eprintStackTrace();

}

}

InputSream 和 OutputStream 中定义了 read() 和 write() 方法,它们被派生流类重载。字节流是字节序

列,它与外部设备中的字节存在着一一对应的关系,不存在字符的转换,被读写字节的个数与外部设备中的字节个数是相同的

基本输入输出方法

System类是Java语言中一个功能强大、非常有用的类,它提供了标准输入/输出及运行时的系统信息

System类不能创建对象,也就是说,System类的所有属性和方法都是静态的,引用时要以System 作为前缀

Systemin与Systemout是System类的两个静态属性,分别对应了系统的标准输入/输出流 System类管理标准输入输出流和错误流

Systemout:把输出送到缺省的显示(通常是显示器),是PrintStream的对象

Systemin:从标准输入获取输入(通常是键盘),是InputStream的对象

Systemerr:把错误信息送到缺省的显示,是PrintStream的对象

同时使用Systemout和Systemerr输出信息不能保证显示顺序就是执行顺序,为了避免这种情况在测试代码执行中经常使用Systemerr输出

FileInputStream、FileOutputStream 顺序读取文件

PipedInputStream、PipedOutputStream 管道

ByteArrayInputStream、ByteArrayOutputStream 内存读写

FilterInputStream、FilterOutputStream 过滤流(有多线程同步)

DataInputStream、DataOutputStream 对数据类型读写,有多线程同步

BufferedInputStream、BufferedOutputStream 缓冲类型读写

1 、使用字节流进行文件的单字节复制

FileInputStream是InputStream的子类,FileInputStream属于节点流,用于按字节读取文件内容

FileOutputStream是OutputStream的子类,FileOutputStream属于节点流,用于按字节输出数据到文件中

//FileInputStream中read方法的定义

/

从指定的输入流中按字节读取数据,如果读到流的末尾则返回-1,否则返回读取到的数据。如果文件不存

在则异常FileNotFoundExceptionIOException的子类

/

public int read() throws IOException {

return read0();

}

//FileOutputStream中write方法的定义

//属性,用于表示是否进行文件的追加 *** 作而不是覆盖 *** 作

private final boolean append;

//构造器方法的定义,其中name是文件名称,默认采用覆盖 *** 作

public FileOutputStream(String name) throws FileNotFoundException {

this(name != null new File(name) : null, false);

}

//按照字节执行写出int数据,自动会去除多余的字节。如果文件不存在则自动创建新文件,如果

文件已经存在则按照append的值决定采用的是追加 *** 作还是覆盖 *** 作

public void write(int b) throws IOException {

write(b, append);

}

private native void write(int b, boolean append) throws IOException; //

由VM采用对等类的方式提供实现

public class Test1 {

public static void main(String[] args) throws IOException {

try (InputStream is = new FileInputStream("c:/面向对象文档txt");

OutputStream os = new FileOutputStream("testtxt");) {

int kk;

while ((kk = isread()) != -1) {

oswrite(kk);

}

}

}

}

2 、读取 Ajava 文件并在控制台上显示

如何使用控制台输出 : Systemout 字节流

分析:使用字节流从 Ajava 中一个字节一个字节的读取内容,然后再使用 Systemoutprint 方法输出即可

注意:读取 *** 作返回的 int 的取值范围为 0-255 ,则表示这里不会有符号位,所以 isread()==-1 不是只适合于文本文件

File ff = new File("T1java");

if (ffexists()) {// 如果文件存在则进行拷贝 *** 作,否则提示文件不存在

InputStream is = new FileInputStream(ff);

OutputStream os = new FileOutputStream("t1bak");

while (true) {

int kk = isread();// 返回值应该是0-255,如果返回-1表示流已经结束

if (kk < 0)break;

oswrite(kk);

}

isclose();

osclose();

} else

Systemoutprintln("T1java文件不存在");

InputStream基本输入类

InputStream类是基本的输入类。它定义了所有输入流所需的方法。

public abstract int read() throws IOException读取一个字节并以整数的形式返回,0-255。如果 返回-1已到输入流的末尾。

public int read(byte b[]) throws IOException读取一系列字节并存储到一个数组,返回实际读取的 字节数。如果已经读到输入流的末尾则返回-1

public void close() throws IOException 关闭输入流并释放资源

public int read(byte b[],int offset,int length) throws IOException功能为从输入流中读数据。这一 方法有几种重载形式,可以读一个字节或一组字节。当遇到文件尾时,返回-1。最后一种形式中的 offset是指把结果放在b[]中从第offset个字节开始的空间,length为长度

public long skip (long n) throws IOEnception 从输入流跳过几个字节。返回值为实际跳过的字节数

OutputStream基本输出类

三个重载形式都是用来向输出流写数据的

public abstract void write(int b)向输入流写入一个字节数据,该字节为参数的低8位。

public void write(byte b[],int offset,int length)将一个字节类型的数组中的从指定位置offset开始 的length个字节写入到输出流

public void close( ) 关闭输出流,释放资源

public void write(byte b[])将一个字节类型的数组中的数据写入到输出流

public void flush() 清除缓冲区,将缓冲区内尚未写出的数据全部输出

字符流

在顶层有 Reader 和 Writer 两个抽象类。 Reader 和 Writer 中定义了 read() 和 write() 方法,它们被派生流类重载

Reader 抽象类的定义

public abstract class Reader implements Readable, Closeable {

//BIO,读取一个有效的字符,返回值为0到65535的整数,如果到达流的末尾则返回-1

public int read() throws IOException

//BIO,读取字符存储到char数组中,返回读取的字符个数,流结束则返回-1

public int read(char cbuf[]) throws IOException

//关闭流,同时释放资源

abstract public void close() throws IOException;

Writer 抽象类的定义

public abstract class Writer implements Appendable, Closeable, Flushable {

//写出一个字符到字符流,要写的字符包含在给定整数值的16个低位;16个高位被忽略。

public void write(int c) throws IOException

//将字符数组中的指定部分内容压入到字符流,从off开始共len个字符

abstract public void write(char cbuf[], int off, int len) throws

IOException;

/关闭流,同时释放资源

abstract public void close() throws IOException;

相关的子类

InputStreamReader、OutputStreamWriter桥接流,用于自动实现字节流和字符流的转换

FileReader、FileWriter文件流,用于实现针对文本文件的读写 *** 作

CharArrayReader、CharArrayWriter内存流,用于实现针对char数组的读写 *** 作

PipedReader、PipedWriter管道流,用于线程之间的通讯

FilterReader、FilterWriter过滤流的父类

BufferedReader、BufferedWriter缓存流,用于在流中添加缓冲区

StringReader、StringWriter内存流,用于实现针对字符串的读写 *** 作

使用字符流实现 txt 文件的读取显示其中包含中文

编写一个程序,读取文件 testtxt 的内容并在控制台输出。如果源文件不存在,则显示相应的错误信息。

字符流 Reader

int read()读取一个字符并以整数的形式返回0-65535,如果返回-1则已到输入流末尾

int read(char[] cbuf)读取一系列字符并存储到一个数组中,返回实际读取的字符数,如果读到输入流末尾则返回-1

void close()关闭输入流并释放内存资源

int read(char[] cbuf, int off, int len) 读取len个字符并存储到一个数组中,从off位置开始,返回实

际读取的字符数,如果读取到输入流末尾则返回-1

long skip(long n)跳过n个字符不读,返回实际跳过的字节数

字符流 Writer

void write(int c) 将字符(int数组的低8位)压入到字符流中

void write(char[] cbuf, int off, int len)将字符数组中的指定部分内容压入到字符流中,从off开始共len个字符

void write(String str) 将字符串中的内容压入到字符流中

void close() 关闭流并释放所占用的资源

void write(String str, int off, int len) 将字符串中的指定部分内容压入到字符流中,从下标off开始共len个字符

void flush()刷新缓冲区,将缓冲区中的数据全部送出到目标地,然后清空缓冲区

void write(char[] cbuf) 将字符数组中的所有数据压入到字符流中

一般来说:一次读写一个字符效率太低,可以引入 char[] 数组提高执行效率

小结

在学些BIO时记忆父类的方法,区分子类的实现不同

InputStream中的方法 read(byte[]):int; Reader中方法read(char[]):int 如果到达流末尾 则-1

OutputStream中的方法 write(byte[],0,len):void;Writer中的方法 write(char[],0,len)/write(String)

一般在使用中,如果读取数据使用字节流,则写出数据采用的也是字节流;不建议混用,除非引入 桥接流

文件流

FileInputStream("file-name") FileInputStream(File) FileNotFoundException

FileReader("file-name") FileReader(File) FileNotFoundException

FileOutputStream("file-name") FileOutputStream("file-name",true) 默认文件覆盖,如果 参数true表示追加

FileWriter("file-name") FileWriter("file-name",true)

一般不使用单字节或者单字符的 *** 作方法,使用数组

注意:try(){}是推荐写法,否则应该使用try{}finally{}结构保证流的关闭

针对二进制文件不建议使用字符流,建议使用字节流进行 *** 作,否则有可能拷贝文件出现问题:

如果针对文本文件则建议使用字符流,因为编码使用比较方便

文章知识点与官方知识档案匹配

Java技能树类和接口类和面向对象

89124 人正在系统学习中

点击阅读全文

打开CSDN,阅读体验更佳

java用于输入输出流的类_java输入输出流_lsgn的博客

java输入输出流 java IO综述 在整个Javaio包中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;一个接口指的是Serializable。 Java I/O主要包括如下几个层次,包含三个部分:

java常见输入输出类型_3分钟秒懂大数据的博客

输入:每行输入一个数,连续输入n行,遇到0结束输入,然后输出结果。 importjavautilArrayList; importjavautilScanner; publicclassTest4{ publicstaticvoidmain(String[] args){ Scannersc=newScanner(Systemin);

25、JAVA进阶——输入输出流

一、认识Java的流 二、使用字节流读写文本文件 1、使用字节流类FileInputStream读文本文件 2、使用字节流类FileOutputStream写文本文件 三、使用字符流读写文本文件 1、使用字符流类BufferedReader和FileReader读文本文件 2、使用字符流类BufferedWrite和FileWrite写文本文件 四、读写二进制文件 1、 使用字节流读二进制文件 2、 使用字节流写二进制文件 五、序列化和反序列化 1、认识序列化 2、序列化保存对

继续访问

java 输入类_java 输入输出类

java中输入输出类如果理不清思路的话就会很混乱!一File类提供与 *** 作系统无关的文件 *** 作!可以查看api文档了解它的方法二输出 *** 作:1把信息输出到屏幕上最简单的 *** 作就是使用标准输出:Systemoutprintln();下面讨论一下流方式的输出,与之相关的类如下OutputStreamWriter:它提供字符流到字节流的转换,换句话说它写入字符数据然后按照指定字符集转换为字节数据Buf

继续访问

JAVA的输入输出_努力的地球人的博客_java输出

Java的输入 Scanner类 为了使用scanner类,我们首先需要导入javautilScanner包 import javautilScanner; 1 创建scanner对象,从用户获取输入 //创建scanner对象 Scanner str=new Scanner(Systemin); //接受用户输入 int w=strnextIn

java输入输出_java中输入输出总结_weixin_39609407的博客

标准输入studin,对象是键盘。 标准输出stdout,对象是屏幕。 标准错误输出stderr,对象也是屏幕。 二、javaio包中的数据流和文件类 字节流:从InputStream和OutputStream派生出来的一系列类。这类流以字节(byte)为基本处理单位。

Java——不同数据类型的输入输出方式与转化方式

java 中不同数据类型的 输入方法 输出格式 与 转化方式

继续访问

Java文本输出常用类

package comssextract; import javaio; import orgapachelog4jLogger; / 结果输出类 @author Shu / public class ResultOutput { private

继续访问

1Java基础入门 -(2)输入输出类_菜鸟的小虫子的博客

一 Java Scanner 类 javautilScanner是 Java5 的新特征,我们可以通过 Scanner 类来获取用户的输入。 Scanner 对象的基本语法: Scanner in= new Scanner(Systemin); 示例1: 输入结果:

java的输入输出流类型_理解JAVA输入输出流_天接云涛的博客

1、字节流抽象类 InputStream输入流 OutputStream输出流 2、字符流抽象类 Reader 输入字符流 Writer 输出字符流 四、JAVA中流体系架构 有一些对流进行 *** 作的基本的方法,我们以文件输入输出流进行说明:

java的输出类

Systemout这个类是PrintStream类,定义如下 public class PrintStream extends FilterOutputStream PrintStream都是用print的相关函数输出到控制台上。print的实现都是用write(String s)实现。 而,PrintWriter这个输出类,也同样实现输出:PrintWriter extends

继续访问

Java中的各种输出形式

一、Java中的各种输出形式: package cnjllwj; public class Demo00 { public static void main(String[] args) { //标识符定义 区分大小写 int a = 5; int A = 6; //区分大小写 int Class = 6; int age = 5; //定义常量 final int AGE_MAX = 30;

继续访问

java中的BIO基础-3

java中的io基础

继续访问

Java学习-IO流进阶

缓冲流也称为高效流、或者高级流。之前学习的字节流可以称为原始流。

继续访问

IO进阶之高级IO

高级IO

继续访问

Java中的IO进阶 *** 作

Java中的IO进阶 *** 作 一、序列化和反序列化 常用于多台服务器之间进行java对象的数据传递。 1概念 序列化 是指程序中准备好的Java对象,永久的保存在磁盘中,这个过程其实是一个out的动作。 ObjectOutputStream:通过在流中使用文件可以实现对象的持久存储。 创建对象:ObjectOutputStream(OutputStream out) 常用方法: void writeObject(Object obj):将指定的对象写入ObjectOutputStream 反序列化 是指把

继续访问

Java IO最详解,欢迎提出意见

Java IO 详解 初学java,一直搞不懂java里面的io关系,在网上找了很多大多都是给个结构图草草描述也看的不是很懂。而且没有结合到java7 的最新技术,所以自己来整理一下,有错的话请指正,也希望大家提出宝贵意见。 首先看个图:(如果你也是初学者,我相信你看了真个人都不好了,想想java设计者真是煞费苦心啊!) 这是java io 比较基本的一些处理流,除此之外我们还会

继续访问

java输出类型_java中各种类型的输入输出

import javalangException;import javalangString;import javautilScanner;public class test {public static void main(String[] args) {Scanner s = new Scanner(Systemin);char ch;Systemoutprint("Char

继续访问

java中输入流的类_Java中的输入/输出流类

Java中包含的输入/输出流类 1javaio包中的接口 (1)处理字节流的有DataInput接口和DataOutput接口,RandomAccessFile同时实现了这两个接口; (2)处理对象流的有ObjectInput接口和ObjectOutput接口,ObjectInputStream类实现了ObjectInput接口,ObjectOutputStream类实现了ObjectOutp

继续访问

使用java的输入/输出类

1. 什么是IO? I:input 输入 通常做读取 *** 作(将不同数据源的数据读入到内存中,也叫读取流) O:output 输出通常做写入 *** 作(将内存中的数据写入到不同的数据源,也叫写入流) 2. 理解流的概念。 想像一下自来水公司要把水输到用户家里,应该先把自来水公司到用户家里的连接水管建好,再将水输出去。管道里输送的是水,但IO里输送的是字节。 u流是

继续访问

Java中的输入/输出流类

Java中包含的输入/输出流类 1javaio包中的接口 (1)处理字节流的有DataInput接口和DataOutput接口,RandomAccessFile同时实现了这两个接口; (2)处理对象流的有ObjectInput接口和ObjectOutput接口,ObjectInputStream类实现了ObjectInput接口,ObjectOutputStream类实现了ObjectOutp

继续访问

最新发布 Java基础自定义一个格式输出类

在项目实际开发中,后端接口都按照一定的格式输出给前端调用,在返回中包括状态码和接口的主要作用等注释,再包含实际的data。

继续访问

IO流(进阶提高)

本篇文章继上一篇IO流(小试牛刀)继续更新JavaIO流的知识。 常见IO流的结构图解: 回顾一下IO的基本接口知识: ————————————————————我是不起眼的分割线———————————————————————— IO的序列化与反序列化 Java序列化是指把Java对象转换为字节序列的过程;Java反序列化是指把字节序列恢复为Java对象的过

继续访问

java进阶8——IO流

File类 File概述 File文件和目录路径名的抽象表示形式。即,Java中把文件或者目录(文件夹)都封装成File对象。也就是说如果我们要去 *** 作硬盘上的文件,或者文件夹只要找到File这个类即可。 File类的构造函数 File(String pathname); // 将一个字符串路径封装成File对象 File(String parent,String child);

继续访问

Java IO流进阶之常用流(一)

请多参考JDK文档:>

java中提供了Future<V>接口和实现了Future接口的FutureTask<V> 类来将线程执行之后的结果返回(通过get()方法)。

1Future<V>接口

Runnable接口执行任务是不返回任何值的,Runnable的run()方法的执行结果是void,而Future接口的call方法是有返回结果的,这是Runnable跟Future的区别之一,它们的另一个不同之处就是实现了Runnable接口的任务执行是调用ExecutorService的execute(Runnable task)方法,而实现了Future接口的任务是调用ExecutorService的submit(Future task)方法。调用Future的get()方法就能直接得到任务的返回值,该方法会一直阻塞直到任务的结果出来为止,我们可以调用Future的isDone()方法来判断该任务的结果是否准备就绪。

[java] view plain copy

import javautilconcurrentCallable;

import javautilconcurrentExecutionException;

import javautilconcurrentExecutorService;

import javautilconcurrentExecutors;

import javautilconcurrentFuture;

public class TestFuture {

public static void main(String[] args) throws InterruptedException, ExecutionException {

ExecutorService executor = ExecutorsnewCachedThreadPool();

Future result1 = executorsubmit(new Callable() {

@Override

public Integer call() throws Exception {

int sum = 0;

for (int i = 0; i < 10; i++) {

sum += i;

}

return sum;

}

});

Future result2 = executorsubmit(new Callable() {

@Override

public Integer call() throws Exception {

int sum = 0;

for (int i = 10; i < 100; i++) {

sum += i;

}

return sum;

}

});

executorshutdown();

Systemoutprintln(result1get() + result2get());

}

}

2FutureTask类

FutureTask实现了Future接口,将一个Callable实例作为参数传给它,就能创建一个FutureTask实例,然后用ExecutorService的submit方法来执行这个实例。最后同样是用get方法获取线程执行后的结果。

[plain] view plain copy

import javautilconcurrentCallable;

import javautilconcurrentExecutionException;

import javautilconcurrentExecutorService;

import javautilconcurrentExecutors;

import javautilconcurrentFutureTask;

public class TestFutureTask {

public static void main(String[] args) throws InterruptedException, ExecutionException {

ExecutorService executor = ExecutorsnewCachedThreadPool();

Callable task = new Callable() {

@Override

public String call() throws Exception {

return "结果";

}

};

FutureTask ft = new FutureTask(task);

executorsubmit(ft);

Systemoutprintln(ftget());

executorshutdown();

}

}empty

以上就是关于java 方法 执行超时处理全部的内容,包括:java 方法 执行超时处理、并发编程解惑之线程、老徐和阿珍的故事:Runnable和Callable有什么不同等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9749670.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-01
下一篇2023-05-01

发表评论

登录后才能评论

评论列表(0条)

    保存