1. 2种实现方法: thread类和runnable接口
extends Thead
packagedemo1;class Runner extendsThread {
@Overridepublic voidrun() {for (int i=0;i<10;i++){
System.out.println("hello"+i);try{
Thread.sleep(100);
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}public classApp {public static voidmain(String[] args) {
Runner r1= newRunner();
Runner r2= newRunner();
r1.start();
r2.start();
}
}
implement runnable
packagedemo2;class Runner implementsRunnable{
@Overridepublic voidrun() {for (int i=0;i<10;i++){
System.out.println("hello "+i);try{
Thread.sleep(100);
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}public classApp2 {public static voidmain(String[] args) {
Thread t1= new Thread(newRunner());
Thread t2= new Thread(newRunner());
t1.start();
t2.start();
}
}
2. volatile
A variable’s value will be modified by different thread. Guaranteed it will not be cached, and different thread will see the update value.
http://stackoverflow.com/questions/17748078/simplest-and-understandable-example-of-volatile-keyword-in-java
http://www.javamex.com/tutorials/synchronization_volatile.shtml
Thevolatilekeyword in Java
3. How to wait until a thread finish running
because start() method return immediately, so main() thread can execute before a thread finish.
packagedemo4;public classApp {private int count = 0;public static voidmain(String[] args) {
App app= newApp();
app.doWork();
}public voiddoWork(){
Thread t1= new Thread(newRunnable(){public voidrun(){for (int i=0;i<10000;i++){
count++;
}
}
});
Thread t2= new Thread(newRunnable(){public voidrun(){for (int i=0;i<10000;i++){
count++;
}
}
});
t1.start();
t2.start();
System.out.println(count);//output before t1 & t2 finish
}
}
use join(), join() will return until thread finish run().
t1.start();
t2.start();try{
t1.join();
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}try{
t2.join();
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(count);//output before t1 & t2 finish
4. synchronized: prevent to access variable at the same time
synchronized method:
packagedemo4;public classApp {private int count = 0;public synchronized voidincrement(){this.count++;
}public static voidmain(String[] args) {
App app= newApp();
app.doWork();
}public voiddoWork(){
Thread t1= new Thread(newRunnable(){public voidrun(){for (int i=0;i<10000;i++){
increment();
}
}
});
Thread t2= new Thread(newRunnable(){public voidrun(){for (int i=0;i<10000;i++){
increment();
}
}
});
t1.start();
t2.start();try{
t1.join();
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}try{
t2.join();
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(count);//output before t1 & t2 finish
}
}
synchronized block:
packagedemo4_2;importjava.util.ArrayList;importjava.util.List;importjava.util.Random;public classWorker {private Random ran = newRandom();private List list1 = new ArrayList();private List list2 = new ArrayList();public synchronized voidstageOne(){try{
Thread.sleep(1);
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
list1.add(ran.nextInt(100));
}public synchronized voidstageTwo(){try{
Thread.sleep(1);
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
list2.add(ran.nextInt(100));
}public voidprocess(){for (int i=0;i<1000;i++){this.stageOne();this.stageTwo();
}
}public voidmain() {
System.out.println("worker");long start =System.currentTimeMillis();
Thread t1= new Thread(newRunnable(){public voidrun(){
process();
}
});
Thread t2= new Thread(newRunnable(){public voidrun(){
process();
}
});
t1.start();
t2.start();try{
t1.join();
}catch(InterruptedException e1) {
e1.printStackTrace();
}try{
t2.join();
}catch(InterruptedException e) {
e.printStackTrace();
}long end =System.currentTimeMillis();
System.out.println("time taken "+ (end-start));
System.out.println("list1 size: "+list1.size());
System.out.println("list2 size: "+list2.size());
}
}
5. Thread pool: Executor Service
http://tutorials.jenkov.com/java-util-concurrent/executorservice.html
ExecutorService
packagedemo5;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.TimeUnit;class Processor implementsRunnable{private intid;public Processor (intid){this.id =id;
}
@Overridepublic voidrun() {
System.out.println("starting :" +id);try{
Thread.sleep(1000);
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("complete :" +id);
}
}public classApp {public static voidmain(String[] args) {long start =System.currentTimeMillis();
ExecutorService es= Executors.newFixedThreadPool(2);//create 2 thread in the thread pool
for (int i=0;i<5;i++){
es.submit(newProcessor(i));//the submitted task will be picked up by any available thread
}
es.shutdown();//you cannot submit new task after shut down
long end =System.currentTimeMillis();
System.out.println("all task submitted :"+(end-start));try{
es.awaitTermination(10, TimeUnit.SECONDS);//wait for a certain time, it will wait less or equal to this time, before doing thing after this line//but it will not terminate anything, it just wait for this time//if you do not shutdown, the wait time will equal to this time//this method is similar to join, but with time constrain
} catch(InterruptedException e) {
e.printStackTrace();
}
end=System.currentTimeMillis();
System.out.println("all task complete :"+(end-start));
}
}
add Future:
future.get(); //returns null if the task has finished correctly.
packagedemo5;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.Future;importjava.util.concurrent.TimeUnit;class Processor implementsRunnable{private intid;public Processor (intid){this.id =id;
}
@Overridepublic voidrun() {
System.out.println("starting :" +id);try{
Thread.sleep(1000);
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("complete :" +id);
}
}public classApp {public static voidmain(String[] args) {long start =System.currentTimeMillis();
ExecutorService es= Executors.newFixedThreadPool(2);//create 2 thread in the thread pool
Future future[] = new Future[5];for (int i=0;i<5;i++){
future[i]= es.submit(newProcessor(i));//the submitted task will be picked up by any available thread
}
es.shutdown();//you cannot submit new task after shut down
long end =System.currentTimeMillis();
System.out.println("all task submitted :"+(end-start));try{
es.awaitTermination(10, TimeUnit.SECONDS);//wait for a certain time, it will wait less or equal to this time, before doing thing after this line//but it will not terminate anything, it just wait for this time//if you do not shutdown, the wait time will equal to this time//similar to join, but with time constrain
} catch(InterruptedException e) {
e.printStackTrace();
}
end=System.currentTimeMillis();for (int i=0;i<5;i++){try{
System.out.println("future :" +future[i].get());
}catch (InterruptedException |ExecutionException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("all task complete :"+(end-start));
}
}
6. CountDownLatch
UseCountDownLatchwhen one thread like main thread, require to wait for one or more thread to complete, before it can start processing.
http://stackoverflow.com/questions/17827022/what-is-countdown-latch-in-java-multithreading
packagedemo6;importjava.util.concurrent.CountDownLatch;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;class Processor implementsRunnable {privateCountDownLatch latch;private intid;public Processor(CountDownLatch la, intid){this.latch =la;this.id =id;
}
@Overridepublic voidrun() {
System.out.println("start:"+this.id);try{
Thread.sleep(3000);
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("end:"+this.id);this.latch.countDown();
}
}public classApp {public static voidmain(String[] args) {
CountDownLatch latch= new CountDownLatch(3);
ExecutorService es= Executors.newFixedThreadPool(3);long start =System.currentTimeMillis();for (int i=0;i<4;i++){
es.submit(newProcessor(latch,i));
}try{
latch.await();//wait until latch count down to 0
} catch(InterruptedException e) {
e.printStackTrace();
}long end =System.currentTimeMillis();
System.out.println("complete count down :"+(end-start));//we have 4 task to submit, and 3 threads in thread pool//it will print after first 3 task finish, the 4th task will be executed after print//if count down from 3, time is 3000; if count 4, time is 6000
}
}
7. BlockingQueue
Items inserted in a particular order are retrieved in that same order — but with the added guarantee that any attempt to retrieve an item from an empty queue will block the calling thread until the item is ready to be retrieved. Likewise, any attempt to insert an item into a queue that is full will block the calling thread until space becomes available in the queue's storage.
http://www.ibm.com/developerworks/java/library/j-5things4/index.html?ca=drs-
5 things you didn't know about ... java.util.concurrent, Part 1
packagedemo7;importjava.util.Random;importjava.util.concurrent.ArrayBlockingQueue;importjava.util.concurrent.BlockingQueue;public classApp {private static BlockingQueue queue = new ArrayBlockingQueue(10);public static void main(String[] args) throwsInterruptedException {
Thread t1= new Thread(newRunnable(){public voidrun(){try{
producer();
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Thread t2= new Thread(newRunnable(){public voidrun(){try{
consumer();
}catch(InterruptedException e) {//TODO Auto-generated catch block
e.printStackTrace();
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}private static void producer() throwsInterruptedException{
Random ran= newRandom();while(true){
queue.put(ran.nextInt(100));
}
}private static void consumer() throwsInterruptedException{
Random ran= newRandom();while(true){
Thread.sleep(100);if (ran.nextInt(10)==0){
Integer va=queue.take();
System.out.println("take value: "+va+" queu size: "+queue.size());
}
}
}
}