欢迎访问宙启技术站
智能推送

多线程函数:创建、同步和通信

发布时间:2023-06-09 08:02:16

多线程是一种同时执行多个任务的技术,它能够提高程序的执行效率和性能,通常用于并发处理、多任务处理、分布式计算等领域。多线程函数是一种对多线程进行管理、调度和控制的函数,它包括创建线程、同步线程和线程间通信等方面。

一、创建线程

在多线程程序中,首先需要创建一个或多个线程,可以使用以下两种方式来创建线程:

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接口能够更加方便地实现线程的管理和协作。