17 Ağustos 2018 Cuma

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();
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
Metodun içi şöyle.
static boolean interrupted ( ) {
  Thread me = Thread.currentThread();
  return me.isInterrupted();
}
Şö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. Şöyle yaparız.
while (!Thread.interrupted()) {
  try {
   ...;
  } catch (InterruptedException e) {
    Thread.currentThread().interrupt(); // restore interrupted status
    return; // or return
  }
}
Yanlış Kullanım
Yanlış kullanım şöyledir.
while (!Thread.currentThread().isInterrupted()) {
  try {
    ...
  } catch (InterruptedException e) {
    ... //Burada bayrak kaldırılmıyor
  }
}
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
Şöyle yaparız.
System.out.println(t.isInterrupted ());
join metodu
Şöyle yaparız.
try {
  t.join ();
} catch (InterruptedException e) {
  ...
}
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 () {...}
}
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
Açıklaması şöyle.
Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority.
setUncaughtExceptionHandler metodu
Bu metod ile setDefaultUncaughtExceptionHandler() farklı çünkü diğer static yani tüm thread'ler için geçerli. Eğer thread tarafından yakalanmamış bir exception gelirse ve thread devam etsin istiyorsak şöyle yaparız.
thread.setUncaughtExceptionHandler((t, e) -> t.run());
Thread dursun istiyorsak şöyle yaparız.
Thread thread = ...;

Thread.UncaughtExceptionHandler h = (t, exception) -> {
  t.interrupt();
};
thread.setUncaughtExceptionHandler(h);
sleep metodu - milisaniye kullanır
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.
Şöyle yaparız.
Thread.sleep (1000);
Şu iki kod aynı işi görür.
Thread.sleep (intervalInMills);
TimeUnit.MILLISECONDS.sleep (intervalInMills);
start metodu
Şöyle yaparız. Thread'i başlatır.
t.start ();
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 (;;) {
  }

}