小编Alm*_*zak的帖子

项目loom,当虚拟线程进行阻塞系统调用时会发生什么?

我正在研究Project Loom 的运作方式以及它能为我的公司带来什么样的好处。

\n

所以我理解其动机,对于基于标准 servlet 的后端,总是有一个执行业务逻辑的线程池,一旦线程因为 IO 而被阻塞,它除了等待之外什么也做不了。假设我有一个具有单个端点的后端应用程序,该端点背后的业务逻辑是使用 JDBC 读取一些数据,该 JDBC 内部使用 InputStream,后者将再次使用阻塞系统调用(就 Linux 而言,为 read())。因此,如果我有 20000 个用户到达此端点,我需要创建 200 个线程,每个线程等待 IO。

\n

现在假设我将线程池切换为使用虚拟线程。根据 Ben Evans 在《深入 Java\xe2\x80\x99s Project Loom 和虚拟线程》一文中的说法:

\n
\n

相反,当进行阻塞调用(例如 I/O)时,虚拟线程会自动放弃(或让出)其承载线程。

\n
\n

据我了解,如果我的操作系统线程数量等于 CPU 核心数量和无限数量的虚拟线程,则所有操作系统线程仍将等待 IO,并且执行程序服务将无法为虚拟分配新工作线程,因为没有可用的线程来执行它。它与常规线程有何不同,至少对于操作系统线程,我可以将其扩展到数千以增加吞吐量。或者我只是误解了 Loom 的用例?提前致谢

\n

添加在

\n

我刚刚读过这个邮件列表

\n
\n

虚拟线程喜欢阻塞 I/O。如果线程需要阻塞(例如 Socket 读取),那么这会释放底层内核线程以执行其他工作

\n
\n

我不确定我是否理解它,如果操作系统执行诸如读取之类的阻塞调用,则操作系统无法释放线程,出于这些目的,内核具有非阻塞系统调用,例如 epoll,它不会阻塞线程并立即返回具有一些可用数据的文件描述符列表。上面的引用是否意味着在幕后,如果调用它的线程是虚拟的, JVM 会将阻塞替换read为非阻塞?epoll

\n

java concurrency multithreading project-loom

18
推荐指数
2
解决办法
4314
查看次数

Spring Boot 在 crudRepository 中使用外键

我有 3 个实体

  • CarWashWash套)
  • Wash( car_wash_idFK 到CarWash)
  • WashComment( wash_idFK 到Wash)

有什么办法可以写这个查询

   @Query(value="select * from wash_comment where wash_comment.wash_id=(select wash_id from wash where wash.car_wash_id=2", nativeQuery=true))
List<WashComment> findAllByCarWashId(CarWash carWash)
Run Code Online (Sandbox Code Playgroud)

不使用 nativeQuery?

spring-data-jpa spring-boot

6
推荐指数
1
解决办法
1万
查看次数

使用rabbitmq推送通知

我想使用rabbitmq向移动应用程序发送通知,问题是我从未使用过amqp协议,所以我需要一些建议

1)正如我从这里读到的http://www.rabbitmq.com/alarms.html如果我发送消息所有消费者都会收到它,我是否需要为每个用户创建单独的队列?

2)我只想在移动应用程序关闭时使用 GCM 发送推送,我可以使用这种结构(弹簧引导)吗?

@Controller
public class SampleController {
    Logger logger = Logger.getLogger(SampleController.class);

   @Autowired
    RabbitTemplate template;

    @RequestMapping("/")
    @ResponseBody
    String home() {
        return "Empty mapping";
    }

    @RequestMapping("/process/{message}")
    @ResponseBody
    String error(@PathVariable("message") String message) {
        logger.info(String.format("Emit '%s'",message));
        String response = (String) template.convertSendAndReceive("query-example-2",message);
        logger.info(String.format("Received on producer '%s'",response));
        if(response==null) {
          sendPushViaGCM(message);
        }
        return String.valueOf("returned from worker : " + response);
    }
Run Code Online (Sandbox Code Playgroud)

3)如果移动应用程序关闭并且我使用gcm发送推送如何从rabbitmq队列中删除消息以避免在应用程序打开时双重推送

4)正如我所建议的,当客户端连接到我的 rabbitmq 服务时,所有其他人将无权侦听其他队列,直到第一个队列未完成。我对吗?一些代码示例将不胜感激

java rabbitmq spring-boot

6
推荐指数
0
解决办法
2917
查看次数

Vertx,多线程如何工作

在 Vertx 官方文档中,我阅读了以下段落

   If a result can be provided immediately, it will be returned immediately, otherwise you will usually provide a handler to receive events some time later.
Because none of the Vert.x APIs block threads that means you can use Vert.x to handle a lot of concurrency using just a small number of threads.
Run Code Online (Sandbox Code Playgroud)

在关于 Reactor 的文章中:

Vert.x works differently here. Instead of a single event loop, each Vertx instance maintains several event loops. By default we choose the …
Run Code Online (Sandbox Code Playgroud)

java multithreading vert.x

6
推荐指数
1
解决办法
3649
查看次数

了解 Tomcat 连接池设置

我想知道我对Tomcat连接池生命周期的理解是否正确。

例如,我有以下设置:

<Resource name="jdbc/appname" auth="Container"
type="javax.sql.DataSource" maxActive="100" 
maxIdle="30" maxWait="1000"
username="username" 
initialSize = "5"
password="password"
driverClassName="jdbc.driver.name"
url="jdbc:protocol://hostname:port/dbname"/>
Run Code Online (Sandbox Code Playgroud)

当我的应用程序部署时它有 5 个连接(初始大小),当所有这些连接都忙时,tomcat 创建并添加到池中一个新连接(6),这个新连接限制是 maxActive(100),当 101 个请求到来时,tomcat将等待 1000 ms(maxWait) 然后抛出 TimeOutException。在某个时间段内只有 40 个连接是忙碌的,当其中一个空闲时它将被销毁,因为池几乎有 30(maxIdle) 个空闲连接。我对吗?

如果我是,那么将 maxIdle 和 maxActive 设置为不同值的目的是什么?

java tomcat database-connection

5
推荐指数
1
解决办法
8043
查看次数

Java:如何以原子方式替换 Map 中的所有值?

我在多线程环境中有一个有状态的 bean,它将其状态保存在地图中。现在我需要一种方法来在一个原子操作中替换该地图的所有值。

public final class StatefulBean {

    private final Map<String, String> state = new ConcurrentSkipListMap<>();

    public StatefulBean() {
        //Initial state
        this.state.put("a", "a1");
        this.state.put("b", "b1");
        this.state.put("c", "c1");
    }

    public void updateState() {
        //Fake computation of new state
        final Map<String, String> newState = new HashMap<>();
        newState.put("b", "b1");
        newState.put("c", "c2");
        newState.put("d", "d1");

        atomicallyUpdateState(newState);
        /*Expected result
         *  a: removed
         *  b: unchanged
         *  C: replaced
         *  d: added*/
    }

    private void atomicallyUpdateState(final Map<String, String> newState) {
        //???
    }
}
Run Code Online (Sandbox Code Playgroud)

目前我ConcurrentSkipListMap用作 a 的实现 …

java concurrency multithreading dictionary

5
推荐指数
1
解决办法
1199
查看次数

UTF-16编码错误的字节

我有一个字符''Unicode值是U + 1F62D二进制等效值为11111011000101101。现在我想将此字符转换为字节数组。我的脚步

1)由于二进制表示形式大于2个字节,因此我使用4个字节

XXXXXXXX XXXXXXX1 11110110 00101101

2)现在我将所有的“ X”替换为“ 0”

00000000 00000001 11110110 00101101

3)十进制等值

00000000(0)00000001(1)11110110(-10)00101101(45)

这是我的代码

@Test
    public void testUtf16With4Bytes() throws Exception {
        assertThat(
                new String(
                        new byte[]{0,1,-10,45},
                        StandardCharsets.UTF_16BE
                ),
                is("")
        );
    }
Run Code Online (Sandbox Code Playgroud)

这是输出

ava.lang.AssertionError: 
Expected: is ""
     but: was "?"
Run Code Online (Sandbox Code Playgroud)

我错过了什么 ?

java unicode utf-16

5
推荐指数
1
解决办法
73
查看次数

虚假共享且不稳定

大家好,我最近发现了 Java 8 中引入的一个注释,称为Contished。从这个邮件列表中,我了解了什么是错误共享以及注释如何允许对象或字段分配整个缓存行。

经过一番研究,我发现如果两个核心存储相同的缓存行,并且其中一个核心对其进行修改,那么第二个核心必须从主内存中重新读取整行。https://en.wikipedia.org/wiki/MESI_protocol。但我仍然不清楚为什么硬件会强制 CPU 重新读取它。我的意思是,这就是为什么我们在 Java 中有一个 volatile 关键字,对吗?如果变量被声明为易失性,那么线程将从缓存中跳过该变量,并始终从主内存中读取/写入它。如果硬件强制 cpu 在每次写入后重新读取缓存行,那么在多线程应用程序中如何可能出现数据不一致?
提前致谢

java caching false-sharing

5
推荐指数
1
解决办法
460
查看次数

如何在 Spring Boot 中处理 DeferredResult 中的异常?

我有一个休息方法:

@RequestMapping(value = "wash/washHistory", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public DeferredResult<String> getWashHistory(@RequestParam(value = "sid", required = true, defaultValue = "") String sid,
            HttpServletResponse response, HttpServletRequest request,
            @RequestParam(value = "sort", defaultValue = "") String sortType,
            @RequestParam(value = "order", defaultValue = "") String order,
            @RequestParam(value = "limit", defaultValue = "") String limit,
            @RequestParam(value = "offset", defaultValue = "") String offset) {

        System.out.println("Thread: "+Thread.currentThread());
        final Integer managerId = checkSession(sid);      
        DeferredResult<String> defResult = new DeferredResult<>();
        new Thread(() -> {
                final String result …
Run Code Online (Sandbox Code Playgroud)

java spring nonblocking spring-boot

4
推荐指数
1
解决办法
3369
查看次数

Spring boot 连接池理解

在 Spring boot application.properties 文件中,我们有以下选项:

server.tomcat.max-threads = 100
server.tomcat.max-connections = 100
spring.datasource.tomcat.max-active = 100
spring.datasource.tomcat.max-idle = 30
Run Code Online (Sandbox Code Playgroud)

这是我的存储库类

public interface UserRepository extends JpaRepository<Users,Integer>{}
Run Code Online (Sandbox Code Playgroud)

这是服务类

@Service
@Transactional(rollbackFor = Exception.class)
public class UserService {

    @Autowired
    private UserRepository userRepository;
    public User getUserById(Integer id){return userRepository.findOne(id)}
Run Code Online (Sandbox Code Playgroud)

问题是,userRepository 如何创建与 DB 的连接以及它是否会使用我的应用程序属性文件中的连接池。我来自 JDBC 和 hibernate,在那里我使用了 DataManager、DataSource、Connection 类来使用连接池,但是在 Spring Boot 中,我没有这些类的任何代码行,一切正常

java spring database-connection spring-boot connection-pool

4
推荐指数
1
解决办法
1万
查看次数