多线程函数:创建、同步和通信
多线程是一种同时执行多个任务的技术,它能够提高程序的执行效率和性能,通常用于并发处理、多任务处理、分布式计算等领域。多线程函数是一种对多线程进行管理、调度和控制的函数,它包括创建线程、同步线程和线程间通信等方面。
一、创建线程
在多线程程序中,首先需要创建一个或多个线程,可以使用以下两种方式来创建线程:
1. 使用Thread类创建线程
Thread类是Java中专门用于创建线程的类,它有一个构造方法,可以接受一个Runnable接口或一个可执行的线程体(即实现了Runnable接口的类或者Lambda表达式)作为参数。例如:
class MyThread extends Thread{
public void run(){
System.out.println("MyThread is running...");
}
}
MyThread myThread = new MyThread();
myThread.start(); // 启动线程
或者
Runnable myRunnable = () -> System.out.println("MyRunnable is running...");
Thread thread = new Thread(myRunnable);
thread.start(); // 启动线程
2. 使用Executor框架创建线程
Java中的Executor框架提供了一种更加灵活的线程管理机制,它可以实现线程的复用、线程池的管理、优先级的设置等。例如:
ExecutorService executor = Executors.newFixedThreadPool(3);
Runnable myRunnable = () -> System.out.println("MyRunnable is running...");
executor.execute(myRunnable); // 启动线程
二、同步线程
多线程程序中,不同的线程可能会访问同一个共享资源,如果不对这些资源进行同步,可能会产生数据不一致的问题。因此,需要使用同步机制来保证共享资源的正确访问。Java中提供了以下两种同步机制:
1. Synchronized关键字
Synchronized关键字可以在方法或代码块前加上,保证同一时刻只有一个线程可以访问共享资源,其他线程需要等待。例如:
class Counter {
private int count = 0;
public synchronized void increment() { // synchronized方法
this.count++;
}
public int getCount() { return this.count; }
}
Counter counter = new Counter();
ExecutorService executor = Executors.newFixedThreadPool(3);
Runnable myRunnable = () -> { counter.increment(); };
for (int i = 0; i < 1000; i++) { executor.execute(myRunnable); }
executor.shutdown();
while (!executor.isTerminated()) {}
System.out.println(counter.getCount()); // 输出1000
或者
class Counter {
private int count = 0;
public void increment() {
synchronized(this){ // synchronized代码块
this.count++;
}
}
public int getCount() { return this.count; }
}
Counter counter = new Counter();
ExecutorService executor = Executors.newFixedThreadPool(3);
Runnable myRunnable = () -> { counter.increment(); };
for (int i = 0; i < 1000; i++) { executor.execute(myRunnable); }
executor.shutdown();
while (!executor.isTerminated()) {}
System.out.println(counter.getCount()); // 输出1000
2. Lock接口
Lock接口提供了一种更加灵活的同步机制,它可以实现可重入锁、公平锁、多条件变量等,同时也可以避免死锁的问题。例如:
class Counter {
private int count = 0;
private Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try{
this.count++;
} finally {
lock.unlock();
}
}
public int getCount() { return this.count; }
}
Counter counter = new Counter();
ExecutorService executor = Executors.newFixedThreadPool(3);
Runnable myRunnable = () -> { counter.increment(); };
for (int i = 0; i < 1000; i++) { executor.execute(myRunnable); }
executor.shutdown();
while (!executor.isTerminated()) {}
System.out.println(counter.getCount()); // 输出1000
三、线程间通信
多线程程序中,不同的线程可能需要进行通信或者协作,例如生产者与消费者模型、读写锁模型等。为了实现线程间的通信或协作,Java中提供了以下两种方式:
1. 使用wait()和notify()方法
wait()和notify()方法是所有Object对象都具有的方法,它们可以用来实现线程间的等待通知机制。例如:
class Product {
private String name;
private boolean hasProduct = false;
public synchronized void produce(String name) {
while (hasProduct) { // 如果已经有产品了,就等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name;
System.out.println("生产者生产了产品:" + name);
hasProduct = true; // 设置有产品了
notifyAll(); // 通知所有等待的线程
}
public synchronized String consume() {
while (!hasProduct) { // 如果没有产品,就等待
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费者消费了产品:" + name);
hasProduct = false; // 设置没有产品了
notifyAll(); // 通知所有等待的线程
return this.name;
}
}
Product product = new Product();
ExecutorService executor = Executors.newFixedThreadPool(2);
Runnable producer = () -> { product.produce("A"); };
Runnable consumer = () -> { product.consume(); };
for (int i = 0; i < 10; i++) {
executor.execute(producer);
executor.execute(consumer);
}
executor.shutdown();
while (!executor.isTerminated()) {}
2. 使用BlockingQueue接口
BlockingQueue接口是Java中用于实现线程间阻塞队列的接口,它可以很方便地实现生产者和消费者模型。例如:
BlockingQueue<String> queue = new LinkedBlockingQueue<>();
ExecutorService executor = Executors.newFixedThreadPool(2);
Runnable producer = () -> {
try {
queue.put("A");
System.out.println("生产者生产了产品:" + "A");
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Runnable consumer = () -> {
try {
String name = queue.take();
System.out.println("消费者消费了产品:" + name);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
for (int i = 0; i < 10; i++) {
executor.execute(producer);
executor.execute(consumer);
}
executor.shutdown();
while (!executor.isTerminated()) {}
四、总结
多线程函数是Java中用于管理、调度和控制多线程的函数,它包括创建线程、同步线程和线程间通信等方面。在编写多线程程序时,需要注意同步机制和线程间通信,以保证程序的正确性和可靠性。同时,使用Executor框架和BlockingQueue接口能够更加方便地实现线程的管理和协作。
