What happens if corePoolSize of ThreadPoolExecutor is 0 - threadpoolexecutor

I'm reading Efficient Android Threading.
It says,
With zero-core threads and a bounded queue that can hold 10 tasks, no tasks actually run until the 11th task is inserted, triggering the creation of a thread.
But when I try code such as,
int N = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor executor = new ThreadPoolExecutor(
0,
N*2,
60L, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(10));
for(int i = 1 ; i <= 5 ; ++i) {
final int j = i;
executor.execute(new Runnable() {
#Override
public void run() {
Log.d("Debug", "Executed : " + j);
SystemClock.sleep(1000);
}
});
Log.d("Debug", "Queued : " + i);
}
The tasks are executed correctly even though there are only 5 tasks in the queue. What am I missing ?

Related

Some confusion about safepoint and -XX:GuaranteedSafepointInterval

My env:
JDK : temurin-1.8.0_332
System: macOS big sur
VM: Hot Spot
GuaranteedSafepointInterval = 1000ms (default)
Q1: The vm param GuaranteedSafepointInterval = 1000ms is really accurately?
public class Test {
public static AtomicInteger count = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
Runnable task = () -> {
for (int i = 0;i < 1000000000;i++){
count.getAndAdd(1);
}
System.out.println(Thread.currentThread().getName() + " done" );
};
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start();
t2.start();
Thread.sleep(1000);
System.out.println("count result = " + count);
}
}
As expect,because of the safepoint, the result is
count result = 2000000000
Thread-1 done
Thread-0 done
But ,if change the main thread sleep time to 800ms...(more you can use <800ms)
result
So, the default value GuaranteedSafepointInterval = 1000ms is really accurately?
Q2: Sometimes,if i still set sleep time = 1000ms,but change the loop content count.getAndAdd(1) to count.getAndAdd(i) ,the "count result" will print after 1s...... as i know,the hot spot vm(jdk=1.8) does some optimizations for 'Counted Loop' when sets savepoint ,(according to the Q1 scence),why it doesnt effective?
Any Can Help Me? More Thanks...

Multithread and Chronicle queue

so I'm trying to see what's the fastest way to write to Chronicle Queue in a multithread env so I have the following:
public static void main(String[] args) throws Exception{
final String path = args[0];
int times = Integer.parseInt(args[1]);
int num = Integer.parseInt(args[2]);
AtomicInteger nextid = new AtomicInteger(0);
ThreadLocal<Integer> id = ThreadLocal.withInitial(() -> nextid.getAndIncrement());
ChronicleTest test = new ChronicleTest();
ChronicleWriter writer = test.new ChronicleWriter(path);
CountDownLatch start = new CountDownLatch(1);
CountDownLatch done = new CountDownLatch(num);
Thread[] threads = new Thread[num];
long[] samples = new long[times * num];
for (int i = 0; i < num; i ++) {
threads[i] = new Thread(new Runnable() {
#Override
public void run() {
try {
start.await();
for (int i = 0; i < times; i++) {
int j = i + times*id.get().intValue();
long s = System.nanoTime();
writer.write(j + " DGirr5JgGVmxhvmaoO0c5MVVOUIEJxWa6nVStPnqmRl3T4hKE9tiwNjn6322uhgr2Fs4hDG8aKYvIB4O0733fx18EqGqNsshaSKoouky5ZekGK3vO87nfSUOz6uDD0olOp35QJQKPgr7tNlFgQP7BImcCyMPFCCm3yhSvOUgiVAD9W9BC3cqlKjQebOG4EkqzRIzwZjxbnIeK2YttfrvOvUJs0e9WBhXUVibi5Ks2j9ROQu2q0PJII4NYyN1a5YW2UKxyng3bRrtBVFqMSamtFzJ23EE4Y7rbQyeCVJhIKRM1LRvcGLUYZqKICWwDtOjGcbXUIlLLYiJcnVRZ4gNRvbFXvTL4XDjhD3uP5S8DjnkeAIBZcQ4VEUf30x65pTGLhWjOMV6jtiEQOWKB3nsuPMhcS1lP3wTQztViW7T8IsQlA5kvVAsnT5A7pojS1CffcYz4a2Rwqf9w6mhTPPZXgpDGArtThW3a69rwjsQxEY9aTwi0Pu0jlSAMmvOA158QFsSeJvLoJXILfocgjNEkj7iVcO0Rc6eC6b5EhJU3wv80EEHnORMXpQVuAuPyao7vJsx06TMcXf9t7Py4qxplVPhptIzrKs2qke2t5A8O4LQzq19OfEQsQGEjqHSbnfWXjfuntuFR8rV4VMyLZO1z3K7HmHtCEy14p5u0C0lj7vmtCnrOum0bnG2MwaAR7DJPIpOtwRObli5K5grv54AWnJyagpRX5e3eTEA8NAKO8oDZuLaoCvgavv9ciFrJcIDmyleVweiVrHs1fQXJoELzFpH4BmvzBuUjfZ8ORSIZsVuq4Hpls19GIA8opb1mSBt7MTifLPauo8WDWRoNi9DvjL4Z08Je6DvrhAFXasU2CMugg5EZ06OXexU17qnvxx2Vz9s9E5U50jDemySZ78KcZ6nqhQKIXUrkTktoEan2JXxI2NNSqEYifwly8ZO2MDquPe4J11rAcOqYp9y6Kb4NtFpNysM1evrLPvCx8oe");
long e = System.nanoTime();
samples[j] = e - s;
}
done.countDown();
} catch (Exception e){
e.printStackTrace();
}
}
});
}
for (int i = 0; i < num; i ++) {
try {
threads[i].start();
} catch (Exception e){
}
}
long startT = System.currentTimeMillis();
start.countDown();
done.await();
long endT = System.currentTimeMillis();
System.out.println("Time to complete [" + times + "] iteration in [" + (endT - startT) + " ms] and threads [" + num + "]");
System.out.println("#######");
for (int i = 0; i < times * num; i ++){
System.out.println(samples[i]);
}
}
private class ChronicleWriter {
SingleChronicleQueue m_cqueue;
ThreadLocal<ExcerptAppender> m_appender;
ChronicleWriter(String path ) {
m_cqueue = SingleChronicleQueueBuilder.binary(path).build();
m_appender = new ThreadLocal<ExcerptAppender>() {
protected ExcerptAppender initialValue() {
return m_cqueue.acquireAppender();
}
};
}
void write(String msg){
m_appender.get().writeText(msg);
}
}
And I ran with parameters:
path 2500 40
For some reason, this keeps crashing with core dump. What am I doing wrong? My disk has lots of disk space so that shouldn't matter. Thanks!!
If your program is crashing due to OutOfMemory error then
note that the disk space and the actual space used by the program may differ.
You may need to increase jvm heap size.
Refer below link to increase jvm heap size
What are the Xms and Xmx parameters when starting JVMs?
Or
Refer below link if you are running your program through eclipse
http://www.planetofbits.com/eclipse/increase-jvm-heap-size-in-eclipse/
I have tried your program with following version of chronicle-queue and it works fine.
<dependency>
<groupId>net.openhft</groupId>
<artifactId>chronicle-queue</artifactId>
<version>4.5.14</version>
</dependency>

Rabbitmq Priority Queue Write Performance Reduced as number of priorities increases

I am using Rabbitmq 3.7.3 with Java client 5.1.2 [amqp-client-5.1.2.jar] for priority queue. In my usecase I will be having maximum of 60 priorities in a single non persistence queue where only few upto 10-15 will be mostly used.
Case 1. If I have defined a queue to have 10 priorities, and messages ranging from 0 to 9 priorities are pushed to the queue, I am getting 12500 writes per second.
Case 2. If I have defined a queue to have 60 priorities, and messages ranging from 0-9 priorities are pushed to the queue, I am getting 4200 writes per second.
Case 3: If I have defined a queue to have 250 priorities, and messages ranging from 0-9 priorities are pushed to the queue, I am getting only 1500 writes per second.
What observed here is, as and when we increase the priorities capacity of a queue, though only very few being used, the write performance degrades.
Below is the code snippet: [Writes are done using single thread]
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.AMQP.BasicProperties;
import java.io.*;
import java.util.*;
public class Write implements Runnable{
int start;
int count;
int end;
private long unixTime;
private long timeTaken;
private long totalTimeTaken;
private long totalRequests;
private long minLatency;
private long maxLatency;
private double avgLatency;
private FileOutputStream out;
int parity = 1;
int ndnc = 0;
int mnp = 1001;
int blist = 0;
String value;
ConnectionFactory factory;
Connection connection;
Channel channel;
String QUEUE_NAME;
public Write(int s, int c){
this.start = s;
this.count = c;
this.end = this.count;
this.totalTimeTaken = 0;
this.totalRequests = 0;
this.minLatency = 1000000;
this.maxLatency = 0;
try{
this.QUEUE_NAME = "queuedata_4";
this.factory = new ConnectionFactory();
factory.setHost("192.168.1.100");
factory.setUsername("user");
factory.setPassword("pass");
this.connection = factory.newConnection();
this.channel = this.connection.createChannel();
Map<String, Object> args = new HashMap<String, Object>();
args.put("x-max-priority", 60);
this.channel.queueDeclare(QUEUE_NAME, false, false, false, args);
}catch(Exception e){
System.out.println("Create Exception"+e);
}
}
public void run(){
String message;
byte[] data = null;
for(int k=this.start; k<=(this.end); k++){
message = "Message_" + k;
unixTime = System.nanoTime();
try{
this.channel.basicPublish(
"",
this.QUEUE_NAME,
new BasicProperties.Builder()
.deliveryMode(1)
.priority(k%10+1)
.build(),
message.getBytes("UTF-8")
);
}catch(Exception e){
System.out.println("New connection made"+e);
}
timeTaken = System.nanoTime() - unixTime;
totalTimeTaken += timeTaken;
if(timeTaken < minLatency){
minLatency = timeTaken;
}
if(timeTaken > maxLatency){
maxLatency = timeTaken;
}
totalRequests ++;
}
avgLatency = totalTimeTaken / totalRequests;
System.out.println("TotalReqs:" + totalRequests + "
TotalTime:" + ((float)totalTimeTaken/1000000.0) + "
MinLatency:" + ((float)minLatency/1000000.0) + " MaxLatency:"
+ ((float)maxLatency/1000000.0) + " AvgLatency:" +
((float)avgLatency/1000000.0));
try{
channel.close();
connection.close();
}catch(Exception e){
System.out.println("Close Exception");
}
}
}

Player should win when all objects are collected

I have a simple game where the player needs to collect 4 game objects within 30 sec. Now I already created the timer, so I need to let the game know that if all game objects are collected under the time limit the player wins.
This is my code so far:
using UnityEngine;
using System.Collections;
public class GameState : MonoBehaviour
{
public static int count = 0;
public float seconds = 30;
public float minutes = 0;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
if (seconds <= 0)
{
seconds = 30;
if (minutes >= 1)
{
minutes -- ;
}
else
{
minutes = 0;
seconds = 0;
GameObject.Find("TimerText").guiText.text = minutes.ToString("f0") + ":0" + seconds.ToString("f0");
}
}
else
{
seconds -= Time.deltaTime;
}
if (Mathf.Round(seconds) <=9)
{
GameObject.Find("TimerText").guiText.text = minutes.ToString("f0") + ":0" + seconds.ToString("f0");
}
else
{
GameObject.Find("TimerText").guiText.text = minutes.ToString("f0") + ":" + seconds.ToString("f0");
}
if(count >= 1)
{
print("You Won!");
}
}
void OnTriggerEnter(Collider collide)
{
if (collide.transform.tag == "Cube")
{
count = count + 1;
Destroy (collide.gameObject);
}
}
}
Note: cube is one of the game object that needs to be picked up.
you could interrupt the game or show a victory menu or something when you have all the cubes collected
void Update ()
{
bool cubescollected = false;
if(cubescollected == 4)
{
ShowVictoryOrSomething();
cubescollected = true
}
if(cubescollected == true)
return;
... your timer code
}
good luck and happy coding

Java executor service How to return total success and total failed record at once

I am inserting records in database using executorserive. Lets say saving 100 records by creating 5 batches each containing 20 records.
ExecutorService e = Executors.newFixedThreadPool(3);
Collection c= new ArrayList();
while (someloop)
{
c.add(mySaveMehtod());
}
List<Future<String>> list = e.invokeAll(c);
Iterator<Future<String>> i= list.iterator();
Future<String> f=null;
while(i.hasNext())
{
f= itr.next();
}
Strin str = f.get();
While processing there might be error for some records and some records will process successfully.
Once process finishes I want to collect total successfully processed and total failed record at once.
Can anybody let me know how I can achieve this ?
Thanks.
Assuming that you know if an INSERT of a record was successful immediately after executing the SQL, you can simply use two AtomicIntegers. You declare them and set to 0 before running batch insert jobs, and increment them in these jobs. Operations on AtomicIntegers are thread safe, so you don't need to worry about synchronization. For example:
public static void main() {
AtomicInteger nSuccess = new AtomicInteger(0);
AtomicInteger nFailed = new AtomicInteger(0);
// add batch insert jobs
// wait for jobs to finish
System.out.println("succeeded: " + nSuccess.get() + " failed: " + nFailed.get());
}
class BatchInserter implements Runnable {
public void run() {
for (int i = 0; i < 20; i++) {
if (insertRecord(i)) {
nSuccess.getAndIncrement();
} else {
nFailed.getAndIncrement();
}
}
}
}