Java ExecutorService
1. implements Callable interface
2. override public T call()
3. create a fixed thread pool
4. create task with Future
5. submit the task with executor.submit(task)
6. check whether the task is done with isDone()
class MyTask implements Callable{
String fname;
public MyTask(String fname){
this.fname = fname;
}
public Integer call(){
return wordCount(fname);
}
}
ExecutorService executor = ExecutorService.newFixedThreadPool(10);
for(String fname : ls){
Future future = executor.submit(() -> wordCount(fname));
if(future.isDone()){
p("wordCount=" + future.get());
}
}
Java Simple Thread
A simple thread can be implemented Runnable interface and override run() method
run() CAN NOT return any value, and CAN NOT throw any Exception
public class HelloThread implements Runnable{
public int num;
public HelloThread(int num){
this.num = num;
}
public void run(){
for(int i=0; i<10; i++){
this.num += 1;
System.out.println("num=[" + num + "]");
}
}
public static void main(String[] args) {
Thread[] array = new Thread[10];
for(int i=0; i<10; i++){
array[i] = new Thread(new HelloThread(1));
array[i].start();
}
}
}
Java Synchronize method 1: keyword synchronized
synchronized void fun(){
count++;
queue.add(count);
}
Java Synchronize method 2: lock the current this object
void fun(){
synchronized(this){
count++;
queue.add(count);
}
}
Java Synchronize method 3: create locked object
private Object lock1 = new Object();
private Object lock2 = new Object();
private long c1;
private long c2;
void fun(){
synchronized(lock1){
c1++;
}
synchronized(lock2){
c2++;
}
}
Java Create simple thread
1: synchronized the method
2: implements Runnable interface, and override run()
class Account{
int sum = 0;
Queue q;
public void Account(){
Queue q = new LinkedList();
}
public synchronized void add(){
sum++;
q.add(sum);
}
}
class MyThread implements Runnable{
Account acc;
public MyThread(Account acc){
this.acc = acc;
}
public void run(){
acc.add();
}
}
// spawn num_threads
Account acc = new Account();
for(int i=0; i < num_threads; i++){
Thread t = new Thread(new MyThread(acc));
t.start();
}
sleep(), wait(), notify() and notifyall() in Java
sleep() - is static method, it can be used in the current thread.
- a sleeping thread can be awaked by interrupt or time expires
wait() - each object has wait() method, and wait() can be used in synchronized block only.
- put the thread to sleep state and release the lock or monitor so that other thread can execute it
- a waiting thread can awaked by notify or notifyall
notify()- each object has notify/notify, and it can be used in synchronized block only.
Java Join Thread, Join waiting for the thread until it die
class TestJoin extends Thread{
public void run(){
for(int i=0; i<5; i++){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("[id=" + getId() + " name=" + getName() + "]["+i+"]");
}
}
}
public class JoinThread {
public static void main(String[] args) {
test1();
}
static void test1(){
Aron.beg();
TestJoin t1 = new TestJoin();
TestJoin t2 = new TestJoin();
TestJoin t3 = new TestJoin();
t1.start();
try{
t1.join(1500);
}catch(Exception e){
}
t2.start();
t3.start();
Aron.end();
}
}
Conditional variables, Condition(), await(), signal() in Java
await() - 1. notFull.await(), release the lock associated with notFull,
2. disable the current thread.
Lock lock = new ReentrantLock();
Condition notFull = lock.newCondition();
Condition notEmpty = new lock.newCondition();
void get(){ // not empty
lock.lock();
try{
while(queue.size() == 0)
notEmpty.await();
x = queue.poll();
notFull.signal();
}finally{
lock.unlock();
}
}
void put(int x){ // not full
lock.lock();
try{
while(queue.size() == MAx)
notFull.await();
queue.add(x);
notEmpty.signal();
}finally{
lock.unlock();
}
}
CountDownLatch() in Java
Lock, Compare And Swap
class MyLock{
private boolean isLocked = false;
public synchronized boolean lock(){
if(!isLocked){
isLocked = true;
return isLocked;
}
return false;
}
public synchronized void unlock(){
isLocked = false;
notify();
}
}