Java 多线程


多线程指一个程序(或单个进程)中同时运行多个线程。


有两种方式创建线程:

  • 通过创建Thread对象,创建一个新线程。
  • 将Runnable对象传给executor对象的execute方法。

创建Thread对象有两种方式:

  • 通过实现Runnable接口,将Runnable对象作为Thread类构造函数的参数。
  • 继承Thread类,重载run方法。

创建Thread类对象

下面是实现Runnable接口的例子:

public class Run implements Runnable {
    public void run() {
        System.out.println("new thread");
    }
    
    public static void main(String[] args) {
        (new Thread(new Run())).start();
    }
}

下面是继承Thread类的例子:

public class SubThread extends Thread {
    public void run() {
        for (int i = 0; i < 20; i++)
            System.out.println("\tnew thread : " + i);
    }
    
    public static void main(String[] args) {
        (new SubThread()).start();
        System.out.println("main thread");
    }
}

线程同步

多个线程可能同时访问同一个资源,例如同时访问某个对象的某个属性。为了保证多线程的安全,需要同步方法或同步语句。

下面是同步方法的例子:

public class SyncMethod implements Runnable {
    Visitor v;

    public SyncMethod(Visitor v) {
        this.v = v;
    }

    public void run() {
        v.incr();
    }

    public static void main(String[] args) {
        Visitor v = new Visitor();
        for (int i = 0; i < 10; i++)
            (new Thread(new SyncMethod(v))).start();
        
        System.out.println("visitor count : " + v.count);
    }
}

class Visitor {
    int count = 0;

    public synchronized void incr() {
        ++count;
    }

    public synchronized void decr() {
        --count;
    }
}

下面是同步语句的例子:

public class SyncStatement implements Runnable {
    Visitor v;

    public SyncStatement(Visitor v) {
        this.v = v;
    }

    public void run() {
        v.incr();
    }

    public static void main(String[] args) {
        Visitor v = new Visitor();
        for (int i = 0; i < 10; i++)
            (new Thread(new SyncStatement(v))).start();
        
        System.out.println("visitor count : " + v.count);
    }
}

class Visitor {
    int count = 0;

    public void incr() {
        synchronized(this) {
            ++count;
        }
    }

    public void decr() {
        synchronized(this) {
            --count;
        }
    }
}

通过Executor接口创建线程

下面是通过Executor接口创建线程的例子:

import java.util.concurrent.Executor;

public class Executor2 implements Executor {
    public void execute(Runnable r) {
        r.run();
    }

    public static void main(String[] args) {
        Executor2 e = new Executor2();
        e.execute(new Run());
        
        System.out.println("\tmain thread");
    }
}

class Run implements Runnable {
    public void run() {
        System.out.println("new thread");
    }
}

下面是通过ExecutorService接口创建线程的例子:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorService2  {
    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(2);
        pool.execute(new Run());
        pool.execute(new Run());
        pool.execute(new Run());
        
        System.out.println("\tmain thread");
    }
}

class Run implements Runnable {
    public void run() {
        System.out.println("new thread");
    }
}

下面是通过ScheduledExecutorService接口创建线程的例子:

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class ScheduledExecutor {
    public static void main(String[] args) {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(new Run(), 1, 1, TimeUnit.SECONDS);
        scheduler.schedule(new Runnable() {
            public void run() {
                future.cancel(true);
            }
        }, 3, TimeUnit.SECONDS);

        System.out.println("\tmain thread");
    }
}

class Run implements Runnable {
    public void run() {
        System.out.println("new thread");
    }
}