首页 > 代码库 > Java Multi-Thread

Java Multi-Thread

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://stackoverflow.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());


        

    }

}