下面我将详细讲解“实例代码讲解JAVA多线程”的完整攻略,包含如下内容:
一、多线程基础知识
1. 线程的概念及创建
线程是指在单个程序中同时运行的多个执行单元,每个线程都有独立的执行路径。Java中通过继承Thread类或实现Runnable接口的方式创建线程,具体代码实例如下:
public class MyThread extends Thread {
public void run() {
System.out.println("MyThread running...");
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
System.out.println("Main thread running...");
}
}
运行以上代码,控制台将输出:
Main thread running...
MyThread running...
这证明主线程和子线程是交替运行的。
2. 线程的状态
Java中线程有五种状态:新建(NEW)、就绪(RUNNABLE)、运行(RUNNING)、阻塞(BLOCKED)和死亡(DEAD)。线程的状态由操作系统内核维护和切换。
3. 线程的同步与互斥
多个线程执行时访问共享资源会发生冲突,需要进行同步或互斥处理,防止出现数据不一致等问题。Java中通过synchronized关键字进行同步,通过Lock接口进行互斥。
二、Java多线程实例
1. 生产者消费者模型
生产者消费者模型是多个线程协作的典型场景,生产者生产数据并交给缓冲区,消费者从缓冲区取出数据进行消费。以下代码实现生产者消费者模型:
public class Producer extends Thread {
private Buffer buffer;
public Producer(Buffer buffer) {
this.buffer = buffer;
}
public void run() {
for (int i=1; i<=10; i++) {
buffer.put(i);
System.out.println("Producer produce: " + i);
try {
Thread.sleep((int)(Math.random() * 200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Producer finished producing.");
}
}
public class Consumer extends Thread {
private Buffer buffer;
public Consumer(Buffer buffer) {
this.buffer = buffer;
}
public void run() {
for (int i=1; i<=10; i++) {
int num = buffer.get();
System.out.println("Consumer consume: " + num);
try {
Thread.sleep((int)(Math.random() * 200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consumer finished consuming.");
}
}
public class Buffer {
private int[] buffer = new int[10];
private int head = 0;
private int tail = 0;
private int count = 0;
public synchronized void put(int num) {
while (count == buffer.length) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
buffer[tail] = num;
tail = (tail + 1) % buffer.length;
count++;
notifyAll();
}
public synchronized int get() {
while (count == 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int num = buffer[head];
head = (head + 1) % buffer.length;
count--;
notifyAll();
return num;
}
}
public class Main {
public static void main(String[] args) {
Buffer buffer = new Buffer();
Producer producer = new Producer(buffer);
Consumer consumer = new Consumer(buffer);
producer.start();
consumer.start();
}
}
这段代码实现了一个简单的生产者消费者模型,通过使用synchronized关键字,实现了对缓冲区的同步访问和互斥访问,生产者可以把数据放入缓冲区,消费者可以从缓冲区取出数据进行消费,两个线程之间互相协作完成工作。
2. 线程池
多线程编程时,频繁地创建和销毁线程会带来大量的资源消耗,此时应该采用线程池的机制,将线程的创建和生命周期管理由线程池来负责。以下代码实现一个简单的线程池:
public class ThreadPool {
private List<WorkerThread> threads = new ArrayList<WorkerThread>();
private LinkedBlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<Runnable>();
private boolean stopped = false;
public ThreadPool(int numThreads) {
for (int i=0; i<numThreads; i++) {
WorkerThread thread = new WorkerThread();
threads.add(thread);
thread.start();
}
}
public void execute(Runnable task) {
synchronized (taskQueue) {
taskQueue.add(task);
taskQueue.notifyAll();
}
}
public void shutdown() {
stopped = true;
synchronized (taskQueue) {
taskQueue.notifyAll();
}
for (WorkerThread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {}
}
}
private class WorkerThread extends Thread {
public void run() {
while (!stopped) {
Runnable task = null;
synchronized (taskQueue) {
if (taskQueue.isEmpty()) {
try {
taskQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
task = taskQueue.poll();
}
if (task != null) {
task.run();
}
}
}
}
}
public class Main {
public static void main(String[] args) {
ThreadPool pool = new ThreadPool(2);
for (int i=1; i<=10; i++) {
final int num = i;
pool.execute(new Runnable() {
public void run() {
System.out.println("Executing task " + num + " on thread " + Thread.currentThread().getName());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
pool.shutdown();
}
}
这段代码实现了一个具备固定线程数的线程池,可以提交多个任务到线程池并按顺序执行,线程池内的线程在任务处理完毕后会一直存在,等待下一个任务的到来。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:实例代码讲解JAVA多线程 - Python技术站