Java并发在实际项目中的标准实践代码

在现代软件开发中,多线程编程已经成为一项关键技能。Java作为一种广泛使用的编程语言,提供了丰富的并发编程工具和库,使得开发者能够更方便地处理多线程编程的挑战。在本文中,我们将介绍一些Java并发编程的标准实践代码,并提供相应的代码示例。

1. 线程的创建和运行

在Java中,我们可以通过继承Thread类或实现Runnable接口来创建一个线程。通常推荐使用实现Runnable接口的方式,因为Java不支持多重继承,使用Runnable接口可以增加代码的灵活性。

下面是一个简单的使用Runnable接口创建和运行线程的示例代码:

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 线程运行时执行的代码
        System.out.println("Hello from MyRunnable!");
    }
}

public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread(new MyRunnable());
        thread.start();
    }
}

这段代码中,我们定义了一个实现了Runnable接口的类MyRunnable,然后在Main类中创建了一个线程并启动它。

2. 线程安全

在多线程编程中,线程安全是一个重要的概念。线程安全意味着多个线程可以安全地访问共享的资源,并且不会产生不确定的结果。在Java中,我们可以使用synchronized关键字来保证线程安全。

下面是一个使用synchronized关键字实现线程安全的示例代码:

public class Counter {
    private int count = 0;

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

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

public class Main {
    public static void main(String[] args) {
        Counter counter = new Counter();

        // 创建多个线程并启动
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    counter.increment();
                }
            });
            thread.start();
        }

        // 等待所有线程完成
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Count: " + counter.getCount());
    }
}

这段代码中,我们创建了一个Counter类来实现计数器功能。通过使用synchronized关键字修饰increment()getCount()方法,我们保证了对count变量的访问是线程安全的。

3. 线程间的通信

在多线程编程中,线程之间需要进行通信以协调各自的工作。Java提供了多种机制来实现线程间的通信,例如使用wait()和notify()方法,以及使用线程安全的队列。

下面是一个使用wait()和notify()实现线程间通信的示例代码:

public class Message {
    private String content;
    private boolean empty = true;

    public synchronized String read() {
        while (empty) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        empty = true;
        notifyAll();
        return content;
    }

    public synchronized void write(String content) {
        while (!empty) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        empty = false;
        this.content = content;
        notifyAll();
    }
}

public class Reader implements Runnable {
    private Message message;

    public Reader(Message message) {
        this.message = message;
    }

    @Override
    public void run() {
        String content = message.read();
        System.out.println("Reader: " + content);
    }
}

public class Writer implements Runnable {
    private Message message;

    public Writer(Message message) {
        this.message = message;
    }

    @Override
    public void run() {
        String[] contents = {"Hello", "World", "Java"};
        for (String content : contents) {
            message.write(content);
            System.out.println("Writer: " + content);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        message.write("Finished");