如你所知,当使用多个线程访问同一个数据时,如果没有同步机制,很容易出现线程安全问题,可能会导致数据不一致,甚至会出现死锁的情况。因此,线程同步是保证程序正确性和性能的重要手段。
可以在程序中加入同步代码块使线程同步,同步代码块的语法格式如下:
synchronized(obj)
{
...
//此处的代码就是同步代码块
}
这里是一个简单的 Java 多线程代码段,使用同步块来确保线程安全:
public class SynchronizedThread implements Runnable {
private int count;
public void run() {
synchronized (this) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + ": " + count);
count++;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
SynchronizedThread synchronizedThread = new SynchronizedThread();
Thread thread1 = new Thread(synchronizedThread);
Thread thread2 = new Thread(synchronizedThread);
thread1.start();
thread2.start();
}
}
在这个例子中,我们创建了一个名为 SynchronizedThread 的类,它实现了 Runnable 接口,并覆盖了 run() 方法。在 run() 方法中,我们使用同步块来确保线程安全。synchronized 关键字将代码块标记为同步,并使用 this 作为互斥锁对象。
我们还创建了两个线程 thread1 和 thread2 ,它们共享同一个 SynchronizedThread 实例,并同时运行。由于我们使用了同步块,这两个线程在访问共享变量 count 时不会发生竞争条件。
Java 多线程安全还可以使用同步方法,同步方法就是使用 synchronized 关键字来修饰某个方法,则该方法为同步方法,通过使用同步方法可以使该方法被多个线程安全地访问。

以下是一个使用同步方法的例子:
public class SynchronizedExample {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
public static void main(String[] args) {
SynchronizedExample example = new SynchronizedExample();
// create multiple threads
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
example.increment();
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
example.increment();
}
}
});
// start the threads
thread1.start();
thread2.start();
// wait for the threads to finish
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// print the final count
System.out.println("Final count: " + example.getCount());
}
}
这个例子中,我们定义了一个类 SynchronizedExample ,其中有一个计数器 count 。我们使用 synchronized 关键字来定义了两个同步方法 increment() 和 getCount() ,以确保多个线程不能同时访问这两个方法。
在 main() 方法中,我们创建了两个线程,并分别启动它们。每个线程都会执行 1000 次 increment() 方法,以增加计数器的值。
最后,我们等待这两个线程完成,然后打印最终的计数器值。由于这两个线程是同步执行的,所以最终的计数器值应该是 2000 。