📜  线程 - Java (1)

📅  最后修改于: 2023-12-03 14:56:50.420000             🧑  作者: Mango

Java线程

Java线程是Java编程语言的核心。线程是一种轻量级进程,使程序可以同时运行多个不同的任务。

创建Java线程

Java线程可通过以下方式创建:

继承Thread类
class MyThread extends Thread {
  public void run() {
    System.out.println("MyThread running");
  }
}

public class Main {
  public static void main(String[] args) {
    MyThread t = new MyThread();
    t.start();
  }
}
实现Runnable接口
class MyRunnable implements Runnable {
  public void run() {
    System.out.println("MyRunnable running");
  }
}

public class Main {
  public static void main(String[] args) {
    MyRunnable r = new MyRunnable();
    Thread t = new Thread(r);
    t.start();
  }
}
使用Callable和Future接口
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

class MyCallable implements Callable<String> {
  public String call() throws Exception {
    return "MyCallable running";
  }
}

public class Main {
  public static void main(String[] args) throws Exception {
    Callable<String> c = new MyCallable();
    FutureTask<String> ft = new FutureTask<>(c);
    Thread t = new Thread(ft);
    t.start();
    System.out.println(ft.get());
  }
}
线程的状态

Java线程可处于以下状态之一:

  • NEW:初始状态,线程已创建但尚未启动。
  • RUNNABLE:运行状态,线程已启动并正在执行。
  • BLOCKED:阻塞状态,线程因等待某个监视器锁而被阻塞。
  • WAITING:等待状态,线程因等待另一个线程执行某个操作而被阻塞。
  • TIMED_WAITING:计时等待状态,线程因等待另一个线程执行某个操作而被阻塞,但最多只会等待指定时间。
  • TERMINATED:终止状态,线程已完成执行。
线程同步

当多个线程同时访问共享资源时,会产生线程安全问题。为了解决这个问题,Java提供了以下机制:

synchronized关键字
class Counter {
  private int count = 0;

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

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

  public synchronized int getCount() {
    return count;
  }
}

public class Main {
  public static void main(String[] args) throws Exception {
    Counter c = new Counter();
    Thread t1 = new Thread(() -> {
      for (int i = 0; i < 1000; i++) {
        c.increment();
      }
    });
    Thread t2 = new Thread(() -> {
      for (int i = 0; i < 1000; i++) {
        c.decrement();
      }
    });
    t1.start();
    t2.start();
    t1.join();
    t2.join();
    System.out.println(c.getCount());
  }
}
ReentrantLock类
import java.util.concurrent.locks.ReentrantLock;

class Counter {
  private int count = 0;
  private ReentrantLock lock = new ReentrantLock();

  public void increment() {
    lock.lock();
    try {
      count++;
    } finally {
      lock.unlock();
    }
  }

  public void decrement() {
    lock.lock();
    try {
      count--;
    } finally {
      lock.unlock();
    }
  }

  public int getCount() {
    lock.lock();
    try {
      return count;
    } finally {
      lock.unlock();
    }
  }
}

public class Main {
  public static void main(String[] args) throws Exception {
    Counter c = new Counter();
    Thread t1 = new Thread(() -> {
      for (int i = 0; i < 1000; i++) {
        c.increment();
      }
    });
    Thread t2 = new Thread(() -> {
      for (int i = 0; i < 1000; i++) {
        c.decrement();
      }
    });
    t1.start();
    t2.start();
    t1.join();
    t2.join();
    System.out.println(c.getCount());
  }
}
线程池

为了避免创建过多线程导致系统资源耗尽,Java提供了线程池。

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

public class Main {
  public static void main(String[] args) throws Exception {
    ExecutorService pool = Executors.newFixedThreadPool(2);
    pool.execute(() -> {
      System.out.println("Task 1 running");
    });
    pool.execute(() -> {
      System.out.println("Task 2 running");
    });
    pool.shutdown();
  }
}
线程间通信

Java提供了以下机制来实现线程间通信:

wait()和notify()方法
import java.util.LinkedList;

class ProducerConsumer {
  private LinkedList<Integer> list = new LinkedList<>();
  private final int LIMIT = 10;
  private Object lock = new Object();

  public void produce() throws InterruptedException {
    int value = 0;
    while (true) {
      synchronized (lock) {
        while (list.size() == LIMIT) {
          lock.wait();
        }
        list.add(value++);
        lock.notify();
      }
    }
  }

  public void consume() throws InterruptedException {
    while (true) {
      synchronized (lock) {
        while (list.size() == 0) {
          lock.wait();
        }
        int value = list.removeFirst();
        System.out.println("Value: " + value);
        lock.notify();
      }
    }
  }
}

public class Main {
  public static void main(String[] args) throws Exception {
    ProducerConsumer pc = new ProducerConsumer();
    Thread t1 = new Thread(() -> {
      try {
        pc.produce();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    });
    Thread t2 = new Thread(() -> {
      try {
        pc.consume();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    });
    t1.start();
    t2.start();
    t1.join();
    t2.join();
  }
}
Condition接口
import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class ProducerConsumer {
  private LinkedList<Integer> list = new LinkedList<>();
  private final int LIMIT = 10;
  private Lock lock = new ReentrantLock();
  private Condition notFull = lock.newCondition();
  private Condition notEmpty = lock.newCondition();

  public void produce() throws InterruptedException {
    int value = 0;
    while (true) {
      lock.lock();
      try {
        while (list.size() == LIMIT) {
          notFull.await();
        }
        list.add(value++);
        notEmpty.signal();
      } finally {
        lock.unlock();
      }
    }
  }

  public void consume() throws InterruptedException {
    while (true) {
      lock.lock();
      try {
        while (list.size() == 0) {
          notEmpty.await();
        }
        int value = list.removeFirst();
        System.out.println("Value: " + value);
        notFull.signal();
      } finally {
        lock.unlock();
      }
    }
  }
}

public class Main {
  public static void main(String[] args) throws Exception {
    ProducerConsumer pc = new ProducerConsumer();
    Thread t1 = new Thread(() -> {
      try {
        pc.produce();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    });
    Thread t2 = new Thread(() -> {
      try {
        pc.consume();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    });
    t1.start();
    t2.start();
    t1.join();
    t2.join();
  }
}
线程安全类

Java提供了以下线程安全类:

  • ConcurrentHashMap
  • CopyOnWriteArrayList
  • ThreadPoolExecutor
  • Semaphore
  • CountDownLatch
  • CyclicBarrier