精华内容
下载资源
问答
  • Java同步组件概况CountDownLatch : 是闭锁,通过一个计数来保证线程是否一直阻塞Semaphore: 控制同一时间,并发线程数量CyclicBarrier:字面意思是回环栅栏,通过它可以实现让一组线程等待至某个状态之后再全部同时执行...

    Java同步组件概况CountDownLatch : 是闭锁,通过一个计数来保证线程是否一直阻塞

    Semaphore: 控制同一时间,并发线程数量

    CyclicBarrier:字面意思是回环栅栏,通过它可以实现让一组线程等待至某个状态之后再全部同时执行。

    ReentrantLock:是一个重入锁,一个线程获得了锁之后仍然可以反复加锁,不会出现自己阻塞自己的情况。

    Condition:配合ReentrantLock,实现等待/通知模型

    FutureTask:FutureTask实现了接口Future,同Future一样,代表异步计算的结果。

    ConditionCondition是多线程之间协调通信的工具类,除了有AQS,还有可能存在Condition队列(不存在或者存在一个以上,即多个等待队列)

    某个或某些线程等待某个Condition,只有当该条件具备(signal或者signAll方法被调用)时,这些等待线程才会被唤醒,从而重新争夺锁。

    Condition是同步器AbstractQueuedSynchronized的内部类,因为Condition的操作需要获取相关的锁,所以作为同步器的内部类比较合理。

    一个 Condition 包含一个等待队列,Condition拥有首节点firstWaiter和尾节点lastWaiter。当前线程调用Condition.await()方法时,将会以当前线程构造节点,并将节点从尾部加入等待队列。

    Condition代码演示package com.rumenz.task;

    import java.util.concurrent.ExecutorService;

    import java.util.concurrent.Executors;

    import java.util.concurrent.atomic.AtomicInteger;

    import java.util.concurrent.locks.Condition;

    import java.util.concurrent.locks.ReentrantLock;

    public class ConditionExample {

    public static void main(String[] args) {

    ReentrantLock reentrantLock=new ReentrantLock();

    Condition condition=reentrantLock.newCondition();

    ExecutorService executorService = Executors.newCachedThreadPool();

    AtomicInteger atomicInteger=new AtomicInteger(0);

    executorService.execute(()->{

    try{

    reentrantLock.lock();

    System.out.println("计算1====开始");

    int i = atomicInteger.addAndGet(10);

    System.out.println("计算1====结果"+i);

    condition.await();

    atomicInteger.incrementAndGet();

    System.out.println("最后结果"+atomicInteger.get());

    } catch (InterruptedException e) {

    e.printStackTrace();

    } finally {

    reentrantLock.unlock();

    }

    });

    executorService.execute(()->{

    try{

    reentrantLock.lock();

    Thread.sleep(5000);

    System.out.println("计算====2");

    int i = atomicInteger.addAndGet(40);

    System.out.println("计算2====结果"+i);

    condition.signal();

    } catch (InterruptedException e) {

    e.printStackTrace();

    } finally {

    reentrantLock.unlock();

    }

    });

    executorService.shutdown();

    }

    }

    //计算1====开始

    //计算1====结果10

    //计算====2

    //计算2====结果50

    //最后结果51

    FutureTaskFutureTask可用于异步获取执行结果或取消执行任务的场景。通过传入Runnable或者Callable的任务给FutureTask,直接调用其run方法或者放入线程池执行,之后可以在外部通过FutureTask的get方法异步获取执行结果,因此,FutureTask非常适合用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果。另外,FutureTask还可以确保即使调用了多次run方法,它都只会执行一次Runnable或者Callable任务,或者通过cancel取消FutureTask的执行等。

    FutureTask代码演示package com.rumenz.task;

    import java.util.ArrayList;

    import java.util.List;

    import java.util.concurrent.ExecutorService;

    import java.util.concurrent.Executors;

    import java.util.concurrent.FutureTask;

    public class FutureTaskExample {

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

    List> futureTasks=new ArrayList<>();

    ExecutorService pool = Executors.newFixedThreadPool(5);

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

    FutureTask futureTask=new FutureTask<>(()->{

    int res=0;

    for (int j = 0; j < 50; j++) {

    res+=10;

    }

    return res;

    });

    futureTasks.add(futureTask);

    pool.submit(futureTask);

    }

    System.out.println("所有任务都已经提交,主线程开始干活");

    Thread.sleep(5000);//模拟主线程的任务

    System.out.println("主进程任务完成,开始获取子线程任务结果");

    int res=0;

    for(FutureTask task:futureTasks){

    try{

    res+=task.get();

    }catch (Exception e){

    e.printStackTrace();

    }

    }

    pool.shutdown();

    System.out.println("最终计算结果:"+res);

    }

    }

    //所有任务都已经提交,主线程开始干活

    //主进程任务完成,开始获取子线程任务结果

    //最终计算结果:5000

    关注微信公众号:【入门小站】,解锁更多知识点

    展开全文
  • 当加载新FXML并设置BorderPane中心时,应用程序会短暂...我正在使用此代码更改centerView:@FXMLpublic void handleChangeView(ActionEvent event) {Task loadTask = new Task<>() {@Overridepublic Par...

    当加载新的FXML并设置BorderPane的中心时,应用程序会短暂“冻结”,无论是来自时间轴还是来自图像视图中的gif,现有动画都将停止.我正在使用此代码更改centerView:

    @FXML

    public void handleChangeView(ActionEvent event) {

    Task loadTask = new Task<>() {

    @Override

    public Parent call() throws IOException {

    String changeButtonID = ((ToggleButton) event.getSource()).getId();

    Parent newOne = getFxmls().get(changeButtonID);

    if (newOne == null) {

    FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/" + changeButtonID + ".fxml"));

    newOne = loader.load();

    getFxmls().put(changeButtonID, newOne);

    }

    return newOne ;

    }

    };

    loadTask.setOnSucceeded(e -> {

    getMainUI().setCenter(loadTask.getValue());

    });

    loadTask.setOnFailed(e -> loadTask.getException().printStackTrace());

    Thread thread = new Thread(loadTask);

    thread.start();

    }

    虽然这确保了在加载时保持UI响应的工作,但是当中心舞台第一次显示时,存在明显的滞后.查看CPU配置文件:

    HpCEK.png

    我不确定延迟是来自初始化函数运行还是加载元素.这是程序的GIF,你可以看到可见的延迟:

    EvLA4.gif

    通过在VLC中加载并逐帧进行,延迟在30 fps视频中看起来是5或6帧,这意味着大约200ms的延迟意味着动画冻结超过50ms左右的初始化方法. (也许整个加载方法会冻结动画?)

    问题是,在这期间可以保持动画流畅吗?

    // ********* EDIT ********** //

    所以我经历了这个项目并尽可能多地删除了一些方法和类,将整个游戏减少到了6个最小的类.我仍然有按下字符按钮(‘你’按钮)的延迟.有了这样一个极小的例子,我迷失了可能是错的.我已将此上传到谷歌驱动器供任何人查看.

    展开全文
  • 通常,您需要将您工作单元封装在Runnable或java.util.concurrent.Callable中,并通过java.util.concurrent.Executor(或org.springframework.core.task.TaskExecutor)执行它们.这允许每个单元工作单独执行,通常以...

    通常,您需要将您的工作单元封装在Runnable或java.util.concurrent.Callable中,并通过java.util.concurrent.Executor(或org.springframework.core.task.TaskExecutor)执行它们.这允许每个单元的工作单独执行,通常以异步方式执行(取决于执行程序的实现).

    所以对于你的具体问题,你可以这样做:

    import java.util.ArrayList;

    import java.util.Iterator;

    import java.util.List;

    import java.util.concurrent.Callable;

    import java.util.concurrent.Executor;

    import java.util.concurrent.FutureTask;

    import org.apache.http.client.methods.HttpGet;

    import org.apache.http.impl.client.BasicResponseHandler;

    import org.apache.http.impl.client.DefaultHttpClient;

    import org.springframework.stereotype.Controller;

    import org.springframework.ui.Model;

    import org.springframework.web.bind.annotation.RequestMapping;

    @Controller

    public class MyController {

    //inject this

    private Executor executor;

    @RequestMapping("/your/path/here")

    public String myMVCControllerGETdataMethod(Model model) {

    //define all async requests and give them to injected Executor

    List tasks = new ArrayList();

    tasks.add(new GetRequestTask("http://api/data?type=1", this.executor));

    tasks.add(new GetRequestTask("http://api/data?type=2", this.executor));

    //...

    //do other work here

    //...

    //now wait for all async tasks to complete

    while(!tasks.isEmpty()) {

    for(Iterator it = tasks.iterator(); it.hasNext();) {

    GetRequestTask task = it.next();

    if(task.isDone()) {

    String request = task.getRequest();

    String response = task.getResponse();

    //PUT YOUR CODE HERE

    //possibly aggregate request and response in Map

    //or do something else with request and response

    it.remove();

    }

    }

    //avoid tight loop in "main" thread

    if(!tasks.isEmpty()) Thread.sleep(100);

    }

    //now you have all responses for all async requests

    //the following from your original code

    //note: you should probably pass the responses from above

    //to this next method (to keep your controller stateless)

    String results = doWorkwithMultipleDataReturned();

    model.addAttribute(results, results);

    return "index";

    }

    //abstraction to wrap Callable and Future

    class GetRequestTask {

    private GetRequestWork work;

    private FutureTask task;

    public GetRequestTask(String url, Executor executor) {

    this.work = new GetRequestWork(url);

    this.task = new FutureTask(work);

    executor.execute(this.task);

    }

    public String getRequest() {

    return this.work.getUrl();

    }

    public boolean isDone() {

    return this.task.isDone();

    }

    public String getResponse() {

    try {

    return this.task.get();

    } catch(Exception e) {

    throw new RuntimeException(e);

    }

    }

    }

    //Callable representing actual HTTP GET request

    class GetRequestWork implements Callable {

    private final String url;

    public GetRequestWork(String url) {

    this.url = url;

    }

    public String getUrl() {

    return this.url;

    }

    public String call() throws Exception {

    return new DefaultHttpClient().execute(new HttpGet(getUrl()), new BasicResponseHandler());

    }

    }

    }

    请注意,此代码尚未测试.

    对于您的Executor实现,请查看Spring’s TaskExecutor和task:executor namespace.您可能需要一个可重用的线程池用于此用例(而不是每次都创建一个新线程).

    展开全文
  • 通常,您需要将您工作单元封装在Runnable或java.util.concurrent.Callable中,并通过java.util.concurrent.Executor(或org.springframework.core.task.TaskExecutor)执行它们.这允许每个单元工作单独执行,通常以...

    通常,您需要将您的工作单元封装在Runnable或java.util.concurrent.Callable中,并通过java.util.concurrent.Executor(或org.springframework.core.task.TaskExecutor)执行它们.这允许每个单元的工作单独执行,通常以异步方式执行(取决于执行程序的实现).

    所以对于你的具体问题,你可以这样做:

    import java.util.ArrayList;

    import java.util.Iterator;

    import java.util.List;

    import java.util.concurrent.Callable;

    import java.util.concurrent.Executor;

    import java.util.concurrent.FutureTask;

    import org.apache.http.client.methods.HttpGet;

    import org.apache.http.impl.client.BasicResponseHandler;

    import org.apache.http.impl.client.DefaultHttpClient;

    import org.springframework.stereotype.Controller;

    import org.springframework.ui.Model;

    import org.springframework.web.bind.annotation.RequestMapping;

    @Controller

    public class MyController {

    //inject this

    private Executor executor;

    @RequestMapping("/your/path/here")

    public String myMVCControllerGETdataMethod(Model model) {

    //define all async requests and give them to injected Executor

    List tasks = new ArrayList();

    tasks.add(new GetRequestTask("http://api/data?type=1",this.executor));

    tasks.add(new GetRequestTask("http://api/data?type=2",this.executor));

    //...

    //do other work here

    //...

    //now wait for all async tasks to complete

    while(!tasks.isEmpty()) {

    for(Iterator it = tasks.iterator(); it.hasNext();) {

    GetRequestTask task = it.next();

    if(task.isDone()) {

    String request = task.getRequest();

    String response = task.getResponse();

    //PUT YOUR CODE HERE

    //possibly aggregate request and response in Map

    //or do something else with request and response

    it.remove();

    }

    }

    //avoid tight loop in "main" thread

    if(!tasks.isEmpty()) Thread.sleep(100);

    }

    //now you have all responses for all async requests

    //the following from your original code

    //note: you should probably pass the responses from above

    //to this next method (to keep your controller stateless)

    String results = doWorkwithMultipleDataReturned();

    model.addAttribute(results,results);

    return "index";

    }

    //abstraction to wrap Callable and Future

    class GetRequestTask {

    private GetRequestWork work;

    private FutureTask task;

    public GetRequestTask(String url,Executor executor) {

    this.work = new GetRequestWork(url);

    this.task = new FutureTask(work);

    executor.execute(this.task);

    }

    public String getRequest() {

    return this.work.getUrl();

    }

    public boolean isDone() {

    return this.task.isDone();

    }

    public String getResponse() {

    try {

    return this.task.get();

    } catch(Exception e) {

    throw new RuntimeException(e);

    }

    }

    }

    //Callable representing actual HTTP GET request

    class GetRequestWork implements Callable {

    private final String url;

    public GetRequestWork(String url) {

    this.url = url;

    }

    public String getUrl() {

    return this.url;

    }

    public String call() throws Exception {

    return new DefaultHttpClient().execute(new HttpGet(getUrl()),new BasicResponseHandler());

    }

    }

    }

    请注意,此代码尚未测试.

    对于您的Executor实现,请查看Spring’s TaskExecutor和task:executor namespace.您可能需要一个可重用的线程池用于此用例(而不是每次都创建一个新线程).

    展开全文
  • 缺点,需要自己实现等待的逻辑,等待变量如果过多,逻辑就会多,代码就是非臃肿,循环多久是不确定。没法精准控制。 二、使用Thread 类join() 阻塞当前线程以等待子线程处理完毕。缺点粒度不够细 三、通过...
  • 80. executor 、task 和 stream ...这个实现几乎就像一件玩具,但即使如此,它还是需要一整页精细代码,如果你实现的不对,就容易出现安全问题或者导致活性失败。幸运是,你再也不需要编写这样代码了。 到本书第
  • rabbitmq 工作队列(java 实现)

    千次阅读 2016-08-23 17:38:23
    rabbitmq HelloWorld ...工作队列(又称:任务队列——Task Queues)是为了避免等待一些占用大量资源、时间操作。当我们把任务(Task)当作消息发送到队列中,一个运行在后台工作者(worker)进程就会取出任务然后
  • Our-Task项目是一个清单管理系统,包括前台系统使用及后台管理系统,基于SpringBoot+MyBatis+Vue实现。该系统前台包括首页、清单管理、分类管理、标签管理、帮助中心等模块。 技术选型 后端技术 技术 说明 版本...
  • Java线程池使用

    2018-07-08 21:53:33
    一、线程池组成 一个线程池包括以下四个基本组成部分:1、线程池管理... 3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务执行,它主要规定了任务入口,任务执行完后收尾工作,任务执...
  • 什么是“异步调用”?...同步调用下面通过一个简单示例来直观理解什么是同步调用:定义Task类,创建三个处理函数分别模拟三个执行任务操作,操作消耗时间随机取(10秒内)package com.kfit.ta...
  • 关于线程理解,我们将一个线程看成是一个任务task,这样应该更好理解。每一个线程就是一个任务,我们要执行一个任务,这个任务如果完成了,那么我们程序功能就得到了实现。因为只有一个CPU,也就是说只有一个...
  • 内容:一个主任务等待两个子任务,通过CyclicBarrierawait()实现。此Runnable任务在CyclicBarrier数目达到后,全部其他线程被唤醒前被运行。 public class CyclicBarrierTest { class MainTask implements ...
  • 顾名思义,这个主要是用于失败了存储,主要用于节点容错,当远程数据交互失败之后,存储在本地,等待远程通信恢复时候,再将数据提交。 FailStore主要用户JobClient任务提交,TaskTracker任务反馈,...
  • Java-CyclicBarrier简单例子

    千次阅读 2015-07-11 15:57:39
    内容:一个主任务等待两个子任务,通过CyclicBarrierawait()实现,此Runnable任务在CyclicBarrier数目达到后,所有其它线程被唤醒前被执行。 public class CyclicBarrierTest { class MainTask implements ...
  • java线程池

    2019-03-01 11:19:32
    线程池主要组件 一个线程池包括以下四个基本组成部分: ... 任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务执行,它主要规定了任务入口,任务执行完后收尾工作...
  • /*** 一个线程池包括以下四个基本组成部分:1、线程池管理...3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务执行,它主要规定了任务入口,任务执行完后收尾工作,任务执行状态等;4、任...
  • Java回调方法(CallBack)

    万次阅读 2021-03-18 09:30:25
    一、前言 在进行应用开发时,不同模块之间存在着...常见有Thread、Task等。 回调 回调机制是: a) 类Aa()方法调用类Bb()方法 b) 类Bb()方法执行完毕主动调用类Acallback()方法 二、例子简介 实现一个
  • java异步-CompletionService

    2019-04-02 20:59:28
    这两者最主要的区别在于submit的task不一定是按照加入自己维护的list顺序完成的。 从list中遍历的每个Future对象并不一定处于完成状态,这时调用get()方法就会被阻塞住, 如果系统是设计成每个线程完成后就能根据其...
  • JAVA 线程 第三版 英文

    2008-11-05 10:26:51
    《Java线程》这一经典图书的新版为你展示出如何完全地运用Java的threading功能且展示出在Java 2 Standard Edition Version 5.0(J2SE 5.0)上最新的变动。本书提供了完整的以及步骤详尽的thread程序设计方法。第一章...
  • java线程池概念.txt

    2019-08-16 10:14:03
    workQueue:一个阻塞队列,用来存储等待执行任务,这个参数选择也很重要,会对线程池运行过程产生重大影响,一般来说,这里阻塞队列有以下几种选择   ArrayBlockingQueue;  LinkedBlockingQueue;  ...
  • Java】线程池

    2020-12-11 15:53:53
    3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务执行,它主要规定了任务入口,任务执行完后收尾工作,任务执行状态等; 4、任务队列(taskQueue):用于存放没有处理任务。提供一种...
  • Java5之后,任务分两类:一类是实现了Runnable接口类,一类是实现了Callable接口类。两者都可以被ExecutorService执行,但是Runnable任务没有返回值,而Callable任务有返回值。并且Callablecall()方法只能...
  • Java线程池及用法

    2017-04-17 21:13:19
    线程池: ...任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务执行,它主要规定了任务入口,任务执行完后收尾工作,任务执行状态等; 任务队列(taskQueue):用于存放没有处理
  • Java线程(第三版).pdf[带书签]

    千次下载 热门讨论 2015-02-12 17:32:23
    常见Threading的实现 总结 第十章Thread Pool 为何要用Thread Pool? Executor 使用Thread Pool Queue与大小 创建Thread Callable Task与Future结果 单一Thread化访问 总结 第十一章Task的调度 Task...
  • 实现的SpeechTranscriberListener对象和SpeechTranscriber对象是一一对应,不能将一个SpeechTranscriberListener对象设置到多个SpeechTranscriber对象中,否则不能区分是哪个识别任务。 Java SDK依赖了Netty网络库...
  • // 用外部工具整个过程都占用了同步量(taskStack).所以应该如何改进...[/color] TaskBean task = taskStack.peekFirst(); if (null != task) { if (!task.getIsConverting()) { task....
  • Java中有3种线程创建方式:实现Runnable接口run方法,继承Thread类并重写run方法,FutureTask方式。 继承Thread优点:run()内获取当前线程直接使用this;缺点:Java不支持多继承(继承了Thread就不能继承其他类...
  • 第六章 任务执行(Task Execution) 在线程中执行任务 最简单策略就是在单个线程中串行地...通过为每个请求创建一个新线程来提供服务,从而实现更高响应性。 对于每个连接,主循环都将创建一个新线程来处理...

空空如也

空空如也

1 2 3
收藏数 55
精华内容 22
关键字:

java的task实现等待

java 订阅