Thread etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Thread etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

11 Ekim 2023 Çarşamba

Thread.ofVirtual metodu - Builder Yöntemi

Giriş
Thread için Builder yöntemini kullanabilmeyi sağlar. Eğer Builder ile uğraşmak istemiyorsak direkt
şöyle yaparız
Thread thread = Thread.startVirtualThread(() -> {
  // your code here
});
Örnek
Şöyle yaparız
Runnable fn = () -> {
  // your code here
};

Thread thread = Thread.ofVirtual(fn)
                      .start();
name metodu
Örnek
Şöyle yaparız
Thread newThread = Thread.ofVirtual()
 .name(jmThread.getThreadName())
 .unstarted(jmThread);
unstarted metodu
Örnek
Şöyle yaparız
public static void main(String[] args) throws Exception {
  var threads = IntStream.range(0, 5).mapToObj(index->Thread.ofVirtual().unstarted(() -> {
    ...
  })).toList();

  threads.forEach(Thread::start);
  for (Thread thread : threads) {
    thread.join();
  }
}
Çıktı şöyle
src [main] ~/jdk-19.jdk/Contents/Home/bin/java --enable-preview main
VirtualThread[#23]/runnable@ForkJoinPool-1-worker-3
VirtualThread[#22]/runnable@ForkJoinPool-1-worker-2
VirtualThread[#21]/runnable@ForkJoinPool-1-worker-1
VirtualThread[#25]/runnable@ForkJoinPool-1-worker-5
VirtualThread[#24]/runnable@ForkJoinPool-1-worker-4
VirtualThread[#25]/runnable@ForkJoinPool-1-worker-3
VirtualThread[#24]/runnable@ForkJoinPool-1-worker-2
VirtualThread[#21]/runnable@ForkJoinPool-1-worker-4
VirtualThread[#22]/runnable@ForkJoinPool-1-worker-2
VirtualThread[#23]/runnable@ForkJoinPool-1-worker-3

Thread.ofPlatform metodu

Giriş
Normalde şöyle yaparız
Runnable fn = () -> {
  // your code here
};

Thread thread = new Thread(fn).start();
ofPlatform metodu
Açıklaması şöyle
Actually, there’s a whole fluent API now, as ofPlatform() returns a Thread.Builder.OfPlatform instance
Örnek
Şöyle yaparız
Thread thread = Thread.ofPlatform().
.start(runnable);
Örnek
Şöyle yaparız
Thread thread = Thread.ofPlatform().
.daemon() .name("my-custom-thread") .unstarted(runnable);

Thread.startVirtualThread metodu

Giriş
Project Loom ile geliyor

Örnek
Şöyle yaparız
for (int i = 0; i < 1_000_000; i++) {
  Thread.startVirtualThread(() -> {
    try {
      Thread.sleep(1000);
    } catch (Exception e) {
      e.printStackTrace();
    }});
}

6 Mart 2023 Pazartesi

Thread.sleep metodu

Giriş
Açıklaması şöyle.
Thread.sleep causes the current thread to suspend execution for a specified period. This is an efficient means of making processor time available to the other threads of an application or other applications that might be running on a computer system.
Açıklaması şöyle.
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.
sleep metodu - long millis
Şöyle yaparız.
Thread.sleep (1000);
Şu iki kod aynı işi görür.
Thread.sleep (intervalInMills);
TimeUnit.MILLISECONDS.sleep (intervalInMills);
sleep(0)
Örnek
Şöyle yaparız
int i = 0;
while (i<10_000_000) {
  // business logic

  //prevent long gc
  if (i % 3000 == 0) {
    try {
      Thread.sleep(0);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}
Buradaki amaç şu değil
.. Thread.sleep(0)is not used to actively give up the CPU time slice,
Amaç şu
GC threads are known to have low priority, so Thread.sleep(0) is used to help GC threads try to compete for CPU time slice
Daha detaylı bir açıklama şöyle. GC işlemi rastgele bir yerde başlamaz. Sadece Safepoint noktalarda başlar. Döngüler Safepoint noktası değildir. Ancak Thread.sleep() bir Safepoint noktasıdır
Taking the HotSpot virtual machine as an example, the JVM does not pause at any position in the code instruction stream to start garbage collection, but forces that the execution must reach a safepoint before pausing. In other words, until the safepoint is reached, the JVM will not stop the world for GC.

The JVM will set safepoints on some loop jumps and method calls. However, in order to avoid the heavy burden of too many safepoints, the HotSpot virtual machine also has an optimization measure for loops. If the number of cycles is small, the execution time should not be too long. Therefore, loops that use int or smaller data types as index values will not be placed with safepoint by default. This kind of loop is called a countable loop. Correspondingly, a loop that uses long or a larger range of data types as index values is called an uncounted loop and will be placed at a safepoint.

However, we happen to have a countable loop here, so our code will not be placed at a safepoint. Therefore, the GC thread must wait until the thread finishes executing and can execute until the nearest safepoint. But if you use Thread.sleep(0), you can place a security point in the code.
Açıklamanın  devamı şöyle. Yani 10 milyon defa dönen bir döngüde arada bir Thread.sleep() kullanarak Safepoint noktası oluşturur ve arada bir GC olmasını sağlar. Böylece döngüden çıkınca uzun bir GC olmasının önüne geçilir.
Thread.sleep(0) is not a useless code. The sleep method can be used to place a safepoint in the java code. It can trigger the GC in a long loop in advance to prevent the GC thread from waiting for a long time, thus avoiding the goal of lengthening the GC time. The people who wrote this code are too strong. It’s really awesome.
sleep metodu - long millis, int nanos
Java 21 için açıklaması şöyle
Thread.sleep(long millis, int nanos) can now perform sub-millisecond sleeps on POSIX platforms. Before, non-zero arguments for nanos were rounded up to a full millisecond before.

Be aware that the actual precision still depends on the underlying system!




30 Mart 2021 Salı

Thread Sınıfı ve Uncaught Exception

Giriş 
Bence uncaught exceptionlar ile uğraşmak yerine, thread döngüsü içinde şöyle yapmak çok daha kolay.

Örnek
Şöyle yaparız
Thread t = new Thread(new Runnable(){
  @Override
  public void run(){
    while(...){
      try{
        ...
      }catch(InterruptedException ex){
        // you'll need to decide whether to ignore or not thread's interruption
        // This example is in case you decide not to ignore it
        ...
      }catch(Exception ex){
        logError(ex);
      } 
    } //while 
 } //run
});

t.start();
Neden Gerekir ?
Bir bir thread eğer unchecked exception'ı yakalamamışsa, Thread.UncaughtExceptionHandler arayüzünden kalıtan bir metod çalıştırılabilir.

Açıklaması şöyle
When a checked exception is thrown inside the run() method of a Thread object, we have to catch and treat it accordingly, because the run() method doesn’t accept a throws clause. But when an unchecked exception is thrown inside the run() method of a Thread object, the default behavior is to write the stack trace in the console (or log it inside the error log file) and exit the program.

However, with UncaughtExceptionHandler interface, Java provides us with a mechanism to catch and treat the unchecked exceptions thrown in a Thread object to avoid the program’s ending abruptly.
Açıklaması şöyle. 
So basically when a thread such as the main thread is about to terminate due to an uncaught exception the virtual machine will invoke the thread’s UncaughtExceptionHandler for a chance to perform some error handling like logging the exception to a file or uploading the log to the server before it gets killed.
İşleyiş sırası şöyle
1. Eğer Thread'e setUncaughtExceptionHandler() atanmışsa tetiklenir.
2. Eğer atanmamışsa, thread'in bağlı olduğu ThreadGroup'a setUncaughtExceptionHandler() atanmışsa tetiklenir. Açıklaması şöyle
Every Thread is a member of a ThreadGroup and if the terminated thread doesn’t have an explicitly set handler than it will forward to the thread group handler. If the thread group doesn’t hold any special handler for such cases, it will eventually call it’s default uncaught exception handler.
3. Eğer hiç biri yoksa default uncaught exception handler tetiklenir

setDefaultUncaughtExceptionHandler metodu
Örnek
Şöyle yaparız
Thread.setDefaultUncaughtExceptionHandler(...);
setUncaughtExceptionHandler metodu
Bu metod ile setDefaultUncaughtExceptionHandler() farklı çünkü diğeri static yani tüm thread'ler için geçerli. 
Örnek - thread'i tekrar çalıştırmak
Açıklaması şöyle
When an exception occurs and call reaches the uncaughtExceptionHandler, the state of the thread is Invalid to start again. So you need to create a new thread and start again.
Elimizde şöyle bir kod olsun. Dolayısıyla bu kod hatalı
thread.setUncaughtExceptionHandler((t, e) -> t.run());
Şöyle yaparız
static AtomicInteger counter = new AtomicInteger();

class MyExceptionHandler implements UncaughtExceptionHandler {
  @Override
  public void uncaughtException(Thread t, Throwable e) {
    
    if (counter.get() == 3) {
      System.out.println("Reached Max. retries, exiting");
    } else {
      counter.incrementAndGet();
      new Thread(new MyTask()).start();
    }
  }
}

class MyTask implements Runnable {
  @Override
  public void run() {
    Thread.currentThread().setUncaughtExceptionHandler(new MyExceptionHandler());
    ...
  }
}
Örnek
Thread dursun istiyorsak şöyle yaparız.
Thread thread = ...;

Thread.UncaughtExceptionHandler h = (t, exception) -> {
  t.interrupt();
};
thread.setUncaughtExceptionHandler(h);

24 Ocak 2021 Pazar

Thread.setPriority metodu

Giriş
Açıklaması şöyle.
Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority.
Not 
Linux'da Thread önceliğini değiştirebilmek için JVM'i başlatırken iki tane parametre verilmes gerekiyor. Bunlar ThreadPriorityPolicy ve UseThreadPriorities. Şöyle yaparız
$ sudo java -XX:ThreadPriorityPolicy=1 -XX:+UseThreadPriorities ThreadPriorityTest &
Sabitler
Java 3 tane sabit veriyor. Açıklaması şöyle
The value can be anything between Thread.MAX_PRIORITY and Thread.MIN_PRIORITY (defined as 10 and 1 respectively). Default is Thread.NORM_PRIORITY with a value of 5.
Örnek
Şöyle yaparız
Thread t = new Thread();
t.setPriority(Thread.currentThread().getPriority() + 1);
t.start();
Örnek
Şöyle yaparız
Thread t1 = ...;
t1.setPriority(Thread.NORM_PRIORITY + 3);
      
Thread t2 = ...;
t2.setPriority(Thread.NORM_PRIORITY - 3);

22 Mayıs 2020 Cuma

Daemon Thread - JVM'in Sonlanmasını Engellemez

Giriş
Daemon yazılmasına rağmen "demon" gibi telaffuz edilir.

Açıklaması şöyle. Normalde JVM en son thread'de bitinceye kadar çalışır. Ancak JVM içinde sadece daemon thread'ler kaldıysa, JVM sonlanır.
Daemon threads are special because if the only threads running in the VM are daemon threads, the Java runtime will shut down or exit.
Örnek
Şöyle yaparız.
Thread t=new Thread();
t.setDaemon(true);

5 Kasım 2019 Salı

Thread ve Interrupt Kullanımı

1. Thread.isInterrupted metodu
Metodun içi şöyle. Kendi içindeki private isInterrupted() metodunu çağırır. Bu metod bayrağı temizlemez!
public boolean isInterrupted ( ) {
  return isInterrupted(false);
}
Örnek
Şöyle yaparız.
System.out.println(t.isInterrupted ());
2. catch (InterruptedException ex) İçinde
Örnek
Bu metod içinde şöyle yapmamalıyız. Çünkü bu exception'ı yakaladıktan sonra hangi kodun çalışacağı ve bizim beklediğimiz bayrağın atanmış olduğu garanti değil.
Thread.currentThread().isInterrupted()
Örnek
Şöyle yaparız. Böylece bayrağın tekrar atanmış olduğunu garanti ederiz.
try {
   queue.poll(3000, TimeUnit.MILLISECONDS);
} catch (InterruptedException ex) {
   ...
   Thread.currentThread().interrupt(); // restore interrupt
}

3. Thread.interrrupted metodu - static
Metodun içi şöyle. Bu metod bayrağı temizler!
static boolean interrupted ( ) {
  Thread me = Thread.currentThread();
  return me.isInterrupted(true);
}
Örnek
Şöyle yaparız.
@Override
public synchronized void run() {
  while(!Thread.interrupted()) {
    ...
  }
}
Koşul ile kullanmak istersek şöyle yaparız.
@Override
public synchronized void run() {
  while (yourFinishCondition && !Thread.interrupted()) {
    ...
  }
}
Doğru Kullanım
Exception yakalandıktan sonra "interrupt status" bayrağını tekrar kaldırmak gerekir.
Örnek
Şöyle yaparız.
while (!Thread.interrupted()) {
  try {
   ...;
  } catch (InterruptedException e) {
    Thread.currentThread().interrupt(); // restore interrupted status
    return; // or return
  }
}
Örnek
Şöyle yaparız
while (!Thread.currentThread().isInterrupted()) {
  try {
    queue.poll(3000, TimeUnit.MILLISECONDS);
  } catch (InterruptedException ex) {
    Thread.currentThread().interrupt();
  }
}
Yanlış Kullanım
Yanlış kullanım şöyledir.
while (!Thread.currentThread().isInterrupted()) {
  try {
    ...
  } catch (InterruptedException e) {
    ... //Burada bayrak kaldırılmıyor
  }
}

24 Eylül 2018 Pazartesi

Thread Sınıfı

Giriş
Her thread "native thread" olarak hayat bulur. Açıklaması şöyle
Each time you start a thread the JVM needs to perform syscalls to allocate the thread stack memory segment and the "red zone" memory segment, and initialize them. (The default thread stack size is typically 500KB or 1MB.) Then there are further syscalls to create the native thread and schedule it.
constructor - default
run metodu override edilmelidir. Şöyle yaparız.
Thread thread = new Thread() {
  @Override
  public void run () {
    ...
  }
};
thread.start ();
Ya da kalıtım ile yaparız.
public class MyThread extends Thread {
  @Override
  public void run() {
    super.run();
      ...
  }
}
constructor - string
Run metodu override edilmelidir. Şöyle yaparız.
static class MyThread extends Thread {
  public MyThread(String s) {
    super(s);
  }
  @Override
  public synchronized void run() {
    ...
  }
}
Şöyle yaparız.
MyThread thread = new MyThread("thread0");
constructor - Runnable
Örnek
Şöyle yaparız.
public class MyTask implements Runnable {
  public void run () {...}
}

Thread thread = new Thread (new MyTask()));
Örnek
Lambda ile şöyle yaparız.
new Thread( () -> {
    ...
}).start();
Örnek
Şöyle yaparız.
Thread thread = new Thread(() -> {...});
thread.start();
constructor - Runnable + string
Şöyle yaparız.
Thread thread = new Thread(() -> {...}, "my thread");
currentThread metodu
Şöyle yaparız.
Thread t = Thread.currentThread();
dumpStack metodu
Standart Stream'e çıktıyı verir.
Örnek
Şöyle yaparız.
Thread.dumpStack()
getAllStackTraces metodu
Şöyle yaparız. Bir map döner. Key olarak Thread sınıfı kullanılır.
System.out.println("Running thread count : " + 
 Thread.getAllStackTraces().keySet().size());
Tüm thread'lerin stack trace çıktısını almak için şöyle yaparız.
Thread.getAllStackTraces()
  .keySet()
  .stream()
  .map(Thread::getStackTrace)
  .map(Arrays::asList)
  .forEach(list -> System.out.println(list.stream()
                                      .map(i -> i.toString())
                                      .collect(Collectors.joining("\n\t"))))
getDefaultUncaughtExceptionHandler metodu
Şöyle yaparız.
Thread.UncaughtExceptionHandler handler =
  Thread.getDefaultUncaughtExceptionHandler();
getId metodu
Şöyle yaparız.
System.out.println(Thread.currentThread().getId());
getName metodu
Şöyle yaparız.
System.out.println(t.getName());
getStackTrace metodu
Açıklaması şöyle
The last element of the array represents the bottom of the stack, which is the least recent method invocation in the sequence.
Şöyle yaparız.
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace()
getState metodu
Açıklaması şöyle
NEW 
A thread that has not yet started is in this state.
RUNNABLE 
A thread executing in the Java virtual machine is in this state.
BLOCKED 
A thread that is blocked waiting for a monitor lock is in this state.
WAITING 
A thread that is waiting indefinitely for another thread to perform a particular action is in this state.
TIMED_WAITING 
A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.
TERMINATED 
A thread that has exited is in this state.
Örnek
Şöyle yaparız.
System.out.println("State of thread : " + thread.getState());
Örnek
Eğer thread başlamadıysa başlatmak için şöyle yaparız.
if (thread.getState() == Thread.State.NEW) {
  thread.start();
}
Örnek
Şöyle yaparız.
if (thread.getState() == Thread.State.TIMED_WAITING) {
  ...
} else if (gameThread.getState() == Thread.State.TERMINATED) {
  ...
} else {
  ...
}
interrupt metodu
Açıklaması şöyle
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
Belirtilen metodlar üzerinde beklemekte olan thread'in içindeki içindeki "interrupt status" bayrağını indirir ve thread'in InterruptedException almasına sebep olur. Şöyle yaparız.
t.interrupt ();
interrrupted metodu - static
Thread ve Interrupt Kullanımı yazısına taşıdım

isAlive metodu
Açıklaması şöyle
A thread is alive if it has been started and has not yet died.
Şöyle yaparız.
while(thread.isAlive ()){...}
isInterrupted metodu
Thread ve Interrupt Kullanımı yazısına taşıdım

join metodu
Şöyle yaparız.
try {
  t.join ();
} catch (InterruptedException e) {
  ...
}
onSpinWait metodu
Java 9 ile geliyor.
Örnek
Şöyle yaparız.
else if ((LockSupport.nextSecondarySeed() & OVERFLOW_YIELD_RATE) == 0)
  Thread.yield();
else
  Thread.onSpinWait();
return 0L;
run metodu
Açıklaması şöyle
The Thread class itself implements Runnable, though its run method does nothing. An application can subclass Thread, providing its own implementation of run,
Eğer Thread nesnesi içine Runnable vermezsek aşağıdaki kod hiç bir şey yapmaz.
Thread t=new Thread();
t.start ();
Thread nesnesini kalıtmamız gerekir.
public class MyThread extends Thread {
  public void run () {...}
}
run vs start açıklaması şöyle
One tricky question I found in various scenarios is how a thread can be started and what is the difference between calling run() and start() methods on a thread instance.

Thread printTrehad = new Thread(() -> System.out.println("..."));
printThread.start();
printThread.run();
printThread.run();

Both method calls are doing the same, they are displaying a text on the console, but the difference is that by calling the start() method, a new thread will be started and will print the text, and if you call the run() method, the text will be displayed by the calling thread.

Another difference is that the run() method can be called multiple times, but the start() method cannot be invoked more than one(the second method call will throw IllegalStateException)
setDeamon metodu
Deamon Thread yazısına taşıdım.

setDefaultUncaughtExceptionHandler metodu - static
Örnek
Şöyle yaparız.
Thread.setDefaultUncaughtExceptionHandler (myHandler);
Handler şöyledir.
Thread.UncaughtExceptionHandler myHandler = new Thread.UncaughtExceptionHandler(){
  @Override
  public void uncaughtException(Thread thread, Throwable ex) {
    ...
  }
};
Handler içinde sanırım yapılabilecek en mantıklı şey exception'ın nereden geldiğini yazdırmak. Şöyle yaparız.
ex.printStackTrace ();
Örnek
Şöyle yaparız.
Thread.setDefaultUncaughtExceptionHandler((thread,t) -> {
  if(t instanceof OutOfMemoryError) {
    System.exit(1);
  }
});
setName metodu
Şöyle yaparız.
Thread t = new Thread(() -> {
  System.out.println("Thread name is " + Thread.currentThread().getName());
});
t.setName("Peter");
t.start();
setPriority metodu
Thread.setPriority yazısına taşıdım

setUncaughtExceptionHandler metodu
Thread Sınıfı ve Uncaught Exception yazısına taşıdım.

sleep metodu - milisaniye kullanır
Thread.sleep metodu yazısına taşıdım

start metodu
Örnek
Şöyle yaparız. Thread'i başlatır.
t.start ();
Örnek
Bitmiş thread tekrar başlatılamaz. Elimizde şöyle bir kod olsun. Bu kod IllegalThreadStateException fırlatır.
mythread.start();       
mythread.join();

mythread.start();   //IllegalThreadStateException
mythread.join();
stop metodu
Bu metod deprecated. Yani kullanılmamalı. Açıklaması şöyle
Why is Thread.stop deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.) If any of the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behavior can result. This behavior may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest itself at any time after the actual damage occurs, even hours or days in the future.
wait metodu
notify() veya interrupt() metodu çağrılıncaya kadar bekler. interrupt() metodu çağrıınca InterruptedException fırlatır. Bunu fırlatınca thread'in interrupted bayrağını temizler. Açıklaması şöyle.
Throws:
InterruptedException - if any thread interrupted the current thread before or while the current thread was waiting. The interrupted status of the current thread is cleared when this exception is thrown.
Örnek
Şöyle yaparız. Çıktı olarak false verir.
public static void main(String args[]) {
  Thread t = new Thread() {
    public void run() {
      try {
        synchronized (this) {
          wait();
        }
      } catch (Exception e) {
        e.printStackTrace();
        System.out.println(Thread.interrupted()); //false
      }
    }
  };
  t.start();

  t.interrupt();
  for (;;) {
  }

}
yield metodu
Açıklaması şöyle
Whenever a thread calls the Thread.yield() method, it gives a hint to the thread scheduler that it is ready to pause its execution. The thread scheduler is free to ignore this hint.

If any thread executes the yield method, the thread scheduler checks if there is any runnable (waiting to be executed) thread with same or high priority than this thread. If the processor finds any thread with higher or same priority then it will switch to a new thread. If not, the current thread keeps executing.