Java多线程 同步互斥
引言
在计算机科学中,多线程是一种使用多个线程执行多个任务的技术。在Java中,多线程编程是非常常见的。然而,当多个线程同时访问共享资源时,可能会出现数据不一致的问题。为了解决这个问题,Java提供了同步和互斥机制。
本文将介绍Java中的多线程编程以及如何使用同步和互斥机制来确保线程安全。
多线程编程基础
多线程编程允许应用程序同时执行多个任务。每个任务在独立的线程中运行,这些线程可以并行执行。
Java中的多线程编程主要依赖于Thread
类和Runnable
接口。下面是一个简单的示例,展示了如何创建和运行线程:
public class MyThread extends Thread {
public void run() {
System.out.println("Hello from MyThread!");
}
}
public class Main {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
System.out.println("Hello from Main!");
}
}
上述代码中,MyThread
类继承自Thread
类,并重写了run
方法。在main
方法中,我们创建了一个MyThread
实例,并调用了start
方法来启动线程。start
方法将会自动调用run
方法。
在运行上述代码时,可能会出现两种输出情况,因为MyThread
和main
方法是并行执行的。
线程同步
当多个线程同时访问共享资源时,可能会导致数据不一致的问题,这种情况称为竞态条件。为了避免竞态条件,我们可以使用线程同步机制。
同步方法
Java中,可以使用synchronized
关键字将方法声明为同步方法。当一个线程调用同步方法时,其他线程将被阻塞,直到该方法执行完毕。
下面是一个使用同步方法的示例:
public class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
public class MyThread extends Thread {
private Counter counter;
public MyThread(Counter counter) {
this.counter = counter;
}
public void run() {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
}
}
public class Main {
public static void main(String[] args) {
Counter counter = new Counter();
MyThread thread1 = new MyThread(counter);
MyThread thread2 = new MyThread(counter);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Count: " + counter.getCount());
}
}
上述代码中,Counter
类有一个count
变量和两个同步方法increment
和getCount
。在increment
方法中,我们使用synchronized
关键字修饰,以确保只有一个线程可以同时访问该方法。
在main
方法中,我们创建了两个MyThread
实例,并传递了同一个Counter
实例。每个线程将会调用increment
方法1000次,然后通过getCount
方法获取计数器的值。
由于increment
方法是同步的,两个线程不会同时访问该方法,从而避免了数据不一致的问题。
同步代码块
除了同步方法,还可以使用同步代码块来实现线程同步。同步代码块使用synchronized
关键字,将一部分代码包裹起来,只有一个线程可以同时执行该代码块。
下面是一个使用同步代码块的示例:
public class Counter {
private int count = 0;
public void increment() {
synchronized(this) {
count++;
}
}
public int getCount() {
synchronized(this) {
return count;
}
}
}
上述代码中,我们在increment
和getCount
方法内