Long可以是null,long不可以。
Long是个Object,long是个primitive
long is a primitive, which must have a value. Simple.
Long is an object, so:
- it can be null (meaning whatever you like, but “unknown” is a common interpretation)
- it can be passed to a method that accepts an Object, Number, Long or long parameter (the last one thanks to auto-unboxing)
- it can be used an a generic parameter type, ie
List
is OK, butList
is not OK- it can be serialized/deserialized via the java serialization mechanism
Always use the simplest thing that works, so if you need any of the features of Long, use Long otherwise use long. The overhead of a Long is surprisingly small, but it is there.
You cannot have multiple consumers -within the same consumer group- consuming data from a single partition.
AdminClient adminClient = AdminClient.create(props);
// I tried and found the props shoud be the same props as your KafkaConfig class.
//Here you get all the consumer groups
List<String> groupIds = adminClient.listConsumerGroups().all().get().
stream().map(s -> s.groupId()).collect(Collectors.toList());
//Here you get all the descriptions for the groups
Map<String, ConsumerGroupDescription> groups = kafkaClient.
describeConsumerGroups(groupIds).all().get();
for (final String groupId : groupIds) {
ConsumerGroupDescription descr = groups.get(groupId);
//find if any description is connected to the topic with topicName
Optional<TopicPartition> tp = descr.members().stream().
map(s -> s.assignment().topicPartitions()).
flatMap(coll -> coll.stream()).
filter(s -> s.topic().equals(topicName)).findAny();
if (tp.isPresent()) {
//you found the consumer, so collect the group id somewhere
}
}
然后悲剧的是,我试了,然后当我同时运行一个程序,这个程序先create一个consumer,再用adminClient找,发现找不到这个consuemr。
所以最后我就放弃这种方法,直接在主文件定义了一个map
所以我又采取了第三种方案,每个方法create和close consumer,然后synchronize这些子方法。
https://www.baeldung.com/java-concurrent-locks
当时不想让两个线程同时创建同一个partition的kafka消费者,想给api endpoint加锁来着,后来发现我可以用synchronized的关键字去sync这些endpoint的函数。
当创建一个新的web request的时候,spring会为它创建一个新的线程, BUT:
用debug模式,然后同时打开三个网页request同一个endpoint,会发现这个endpoint下的function是被依次执行三遍的。从不同的PC发出request应该也是这样。看似不同web request的线程之间是相互block的。
但是,又说spring是线程不安全的,处理这些线程安全是开发者的任务。
所以猜测,spring内部有一些它自己线程的机制… 不是说一定不安全,一定会并发,但是不保证一个web request线程运行时,一定会block其他web request线程吧… 总而言之,还是自己处理一些不同web request之间的synchronize问题吧?
在没有synchronized的情况下,如果用多线程call同一个接口,不一定要url一样,大概就是同一个address:port,就会报错:ConnectionClosedException
但是不明白,为什么debug的情况下,当我们调用一个endpoint,这时候再开一个新的浏览器窗口,这个新的不会被运行,直到第一个调用被处理完
Every new HTTP request generates a new thread.
If the container creates a new bean instance just for that particular request, we can say this bean is thread-safe.
If two different threads execute a method of the singleton at the same time, you’re not guaranteed that both calls will be synchronized and run in the sequence.
正如3中所说,我运行的时候用着debug模式,然后当前request正在processing的时候,我call了另一个request,看似另一个request一直没有被执行,直到当前的执行完?而且debug console里的thread在重新call了一个request后并没有任何改变?。。。debug console里还是有不止一个在running的endpoints的,因为call一个request就会开启多个thread。
但是我还是不懂two different threads execute a method of the singleton at the same time这种情况怎么会发生?明明另一个request完全被block了啊。可能spring内部机制…不能保证总是这样吧…
In other words, it’s your responsibility to ensure your code runs safely in the multithreaded environment. Spring won’t do that for you.
As you know, some user’s requests may be concurrent. Because of that fact, session beans aren’t thread-safe.
What about the request scope bean? Spring creates a new instance of such component for each web request. Each request is bound to a separate thread. Therefore, each instance of the request bean gets its own instance of the prototype(不像singleton的thread-unsafe) bean. In that case, you can consider the prototype as thread-safe.
感觉这种是我的情况。不,不是,我就没创建prototype bean应该。
when you define a controller as the prototype, the Spring framework will create a new instance for each web request it serves.
The bean is stateless if execution of its methods doesn’t modify its instance fields.
Usually, your beans have some fields.
这个例子是写了一个Thread.sleep,但是在运行时,发现第一个request还在sleep的时候,第二个request已经开始运行了, “To my surprise Spring doesn’t block incoming requests.” 这个和我debug时发现的就恰好相反,这些request之间没有互
相block,即使用了sleep,还是阻止不了其他request的开始执行。
原因好像可以参考tomcat thread pool,另外有人给出解释:
It’s blocking in the sense that it blocks one thread: the thread taken out of the pool of threads by the servlet container (Tomcat, Jetty, etc., not Spring) to handle your request. Fortunately, many threads are used concurrently to handle requests, otherwise the performance of any Java web application would be dramatic.
If you have, let’s say, 500 concurrent requests all taking 1 minute to complete, and the pool of threads has 300 threads, then 200 requests will be queued, waiting for one of the threads to become available
大概就是说,不同的web request是由不同的thread来handle的,你只sleep/block当前运行它的thread而已。可能thread pool同时有两个可用的thread,那么被queue的这些web requests中就有两个会同时开始被两个thread执行。
我为什么需要用synchronized? 我的代码是如下情境:
Each time, when make web request, will create a different consumer, what will happen if 5 endpoints are making request, but only 4 partitions? The 5th will failed, since each consumer will assign to only one partition in my code.
加上spring又不会替我们管理线程。
When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that method’s object and releases it when the method returns. The lock release occurs even if the return was caused by an uncaught exception.
You might wonder what happens when a static synchronized method is invoked, since a static method is associated with a class, not an object. In this case, the thread acquires the intrinsic lock for the Class object associated with the class. Thus access to class’s static fields is controlled by a lock that’s distinct from the lock for any instance of the class.
其实我找了那些lock不lock的,我都是想找个方法让不同的method之间相互block,也就是这些methods不能同时被run。后来发现其实很简单,用synchronize这个keyword就可以实现。用法也很简单,用了多线程测试,也的确实现了方法间互相block。
public class Example {
private int value = 0;
public synchronized int getNextValue(){
return value++;
}
}
With that, you have a guarantee that only one thread can execute the method at the same time. The used lock is the
intrinsic lock of the instance
. If the method is static, the used lock is theClass
object ofExample
. If you have two methods with the synchronized keyword, only one method of the two will be executed at the same time because the same lock is used for the two methods. 6中也提到了。
等同于:
public int getNextValue() {
synchronized (this) {
return value++;
}
}
if you don’t want to use the intrinsic lock of the current object but another object, you can use another object just as a lock:
private final Object lock = new Object();
public int getNextValue() {
synchronized (lock) {
return value++;
}
}
The lock is internal to the object so no other code can use the lock.
看着有点麻烦,没有深究,直接把那个class改成不是bean的了。而且本来,之前提到过,bean最好是stateless的,会线程更安全啥的,在5中提到,而有fields的bean不是stateless的。
什么叫有fields的,就是有成员变量的:
@Component
public class customResponse{
private String id; // field
private String status; // field
}
Things that happen within the finally block are guaranteed to occur no matter what happens in the try-catch-block. If an exception happens that is not encapsulated by Exception (e.g., extends Throwable, such as various Errors), then it still runs the finally block.
framework | path segment | http query parameter |
---|---|---|
Jersey (JAX-RS) | @PathParam | @QueryParam |
Spring RESTFul | @PathVariable | @RequestParam |
example | http://xyz.ir/{segment} | http://xyz.ir/?param{param} |
我用的@QueryParam,路径其实是:
@Path(http://xyz.ir/param)
call的时候用:
http://xyz.ir/param?a=2&b=3
当一个线程在执行synchronized 的方法内部,调用了wait()后, 该线程会释放该对象的锁, 然后该线程会被添加到该对象的等待队列中(waiting queue), 只要该线程在等待队列中, 就会一直处于闲置状态, 不会被调度执行。
zipkin: track rest call to see if success or fail, usually used in distributed environment.
rest-proxy: let my project call other projects max.
一个被@Bean标注的method,在被@Inject到 Junit的Integration test时,会有红色波浪线说找不到bean,但其实debug和运行都能找到。然后在JUnit这个test class上加上@Component,红波浪线就消失了。
但其实那些有component 标注的class(不是method),就算@Inject到没有@Component的test class,也不会画红波浪线的。所以这里不应该有问题。
反正感觉有没有红波浪线,有@Bean,@Component的都是能注入到JUnit没有@Component的test class的。
网上有的解答实在build.gradle sourceset里写明integration test,而且java里面有main test integrationTest三个文件夹,但其实我的情况,只要把test里class改成以IT结尾,那么就能被识别为Integration test。
处理kafka的时候,虽然核心代码(用到kafka broker,和kafka相关部分的代码)是依次进行的,但不知道为啥三个进程同时在获取删除embeddedkafka的文件。
而且,即使只run一个testcase,log里仍然会有三次kafkaconfig的记录(应该不影响),而且总会有can’t deleting log since other processes are using it这样的error。
所以和多线程啥的无关,这个错误据说是kafka内部在windows上的错,我尝试了:
https://stackoverflow.com/questions/57622587/spring-kafka-test-with-embedded-kafka-failed-on-deleting-logs
https://issues.apache.org/jira/browse/KAFKA-8145
https://issues.apache.org/jira/browse/KAFKA-1194
https://stackoverflow.com/questions/12558231/recompile-with-xlintdeprecation-for-details
https://stackoverflow.com/questions/8215781/how-do-i-compile-with-xlintunchecked
按如下设置了xlint 感觉没有用啊…
For IntelliJ 13.1, go to File -> Settings -> Project Settings -> Compiler -> Java Compiler, and on the right-hand side, for Additional command line parameters enter “-Xlint:unchecked”.
许多地方给我的感觉是有spring context的是integration test. 那么既然都有spring context,为什么我们在build gradle的时候,要选一些为Integration test呢?
好像是因为用到restTemplate这样,验证web request的,习惯标注为Integration test。
https://www.petrikainulainen.net/programming/gradle/getting-started-with-gradle-integration-testing/
https://stackoverflow.com/questions/54658563/unit-test-or-integration-test-in-spring-boot
https://stackoverflow.com/questions/10752/what-is-the-difference-between-integration-and-unit-tests
一个神奇的发现,如果一个thread run里只有logger.info和Thread.sleep,那么thread.start()的时候,会报nullpointerexception,debug的时候这个thread明明不是null,但是start的时候好像以为thread是null。但是改成system.out.println()就不会了。。。。不知道这是为什么
https://stackoverflow.com/questions/48273219/significance-of-spring-application-name-in-bootstrap-properties
"Per the useSelector API docs, useSelector relies on reference equality, not shallow equality. "
When the selector does only depend on the state, simply ensure that it is declared outside of the component so that the same selector instance is used for each render:
记得点标题的超链接,讲的非常好,看完以后我就把不能re-redender的bug解决了。
This is an ES2015 (also called ES6) shorthand to create objects.
{ product } is equivalent to { product: product }.
Basically, you end up with an object with a property called “product” that has the value of the product variable.
在trigger的时候,state里的respData就已经更新了,导致success的时候发现state没有更新,因此没有render界面,原因不明,但尝试了以下解决方法:
其实我删了那些文件后,好像也没有回来了,搜到以下这些,仅供参考:
unwanted js file and js-map files are being generated from ts
This will be caused by some process invoking the tsc command with a different configuration to the one you gave in your question.
In your visual studio project settings have a look for typescript options and try disabling compile on save / similar
Also, it would be worth checking your project directory for any other tsconfig files, in case there is another configuration that is causing the incorrect behavior.
Of course you’ll need to manually remove the two files and see if they come back after making any changes