1. 2种实现方法: thread类和runnable接口
extends Thead
package demo1; class Runner extends Thread { @Override public void run() { 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 class App { public static void main(String[] args) { Runner r1 = new Runner(); Runner r2 = new Runner(); r1.start(); r2.start(); } }
implement runnable
package demo2; class Runner implements Runnable{ @Override public void run() { 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 class App2 { public static void main(String[] args) { Thread t1 = new Thread(new Runner()); Thread t2 = new Thread(new Runner()); 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://*.com/questions/17748078/simplest-and-understandable-example-of-volatile-keyword-in-java
Simplest and understandable example of volatile keyword in java
http://www.javamex.com/tutorials/synchronization_volatile.shtml
The volatile keyword 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.
package demo4; public class App { private int count = 0; public static void main(String[] args) { App app = new App(); app.doWork(); } public void doWork(){ Thread t1 = new Thread(new Runnable(){ public void run(){ for (int i=0;i<10000;i++){ count++; } } }); Thread t2 = new Thread(new Runnable(){ public void run(){ 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:
package demo4; public class App { private int count = 0; public synchronized void increment(){ this.count++; } public static void main(String[] args) { App app = new App(); app.doWork(); } public void doWork(){ Thread t1 = new Thread(new Runnable(){ public void run(){ for (int i=0;i<10000;i++){ increment(); } } }); Thread t2 = new Thread(new Runnable(){ public void run(){ 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:
package demo4_2; import java.util.ArrayList; import java.util.List; import java.util.Random; public class Worker { private Random ran = new Random(); private List<Integer> list1 = new ArrayList<Integer>(); private List<Integer> list2 = new ArrayList<Integer>(); public synchronized void stageOne(){ try { Thread.sleep(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } list1.add(ran.nextInt(100)); } public synchronized void stageTwo(){ try { Thread.sleep(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } list2.add(ran.nextInt(100)); } public void process(){ for (int i=0;i<1000;i++){ this.stageOne(); this.stageTwo(); } } public void main() { System.out.println("worker"); long start = System.currentTimeMillis(); Thread t1 = new Thread(new Runnable(){ public void run(){ process(); } }); Thread t2 = new Thread(new Runnable(){ public void run(){ 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()); } }