线程同步是一种建立多个尝试访问共享资源的线程之间合作的方式。它对于可靠的线程交互是必要的,并且是通过使用'synchronized'关键字来完成的。在这里,线程是一个大操作中的小子过程。在本文中,我们将学习静态同步以及它们如何管理线程以便它们能够高效地工作。
多线程
多线程是 Java 编程语言的一个特性,允许同时执行多个操作。在这个过程中,操作被分成多个更小的部分,称为线程。每个线程独立执行一个任务而不影响其他线程的性能。多线程的主要好处是对资源如 CPU 的最优使用,并且它提高了分配操作的执行时间。
同步
线程是以异步方式执行的,因此不可能预测它们将如何交互。有时,几个线程可能会尝试访问单一资源,这时就会出现问题,因为它可能会产生分配任务的错误结果。此时,同步就变得重要起来,它确保了单个线程一次只能访问给定的资源。这是可能的,因为有一个锁定对象守护着同步区域。当一个线程进入该区域时,锁就被赋予它,并且在执行完其任务后释放锁。直到资源被占用,其他线程会在队列中等待它们的机会。
Java 中的静态同步
当我们使用这种类型的同步时,如果一个线程处于静态同步区域,所有其他试图访问这个区域的线程将被阻塞。由于静态方法属于类,因此静态同步适用于类级别的锁。
静态同步的语法
static synchronized returnType nameOfMethod( Type parameters) {
}
这里 returnType
可能是 void
或任何原始数据类型。parameters
包含变量名后面跟着的是数据类型。
没有静态同步的多线程
这是一个简单的例子,它可能会也可能不会按顺序打印计数器值,每次运行时,根据线程获得的 CPU 时间的不同,会产生不同的结果。
没有静态同步的多线程示例
package com.tutorialspoint;
class PrintDemo {
public static void printCount() {
try {
for(int i = 5; i > 0; i--) {
Thread.sleep(50);
System.out.println("Counter --- " + i );
}
} catch (Exception e) {
System.out.println("Thread interrupted.");
}
}
}
class ThreadDemo extends Thread {
private Thread t;
private String threadName;
ThreadDemo( String name) {
threadName = name;
}
public void run() {
PrintDemo.printCount();
System.out.println("Thread " + threadName + " exiting.");
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
public class TestThread {
public static void main(String args[]) {
ThreadDemo t1 = new ThreadDemo( "Thread - 1 " );
ThreadDemo t2 = new ThreadDemo( "Thread - 2 " );
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch ( Exception e) {
System.out.println("Interrupted");
}
}
}
输出
每次运行此程序都会产生不同的结果:
Starting Thread - 1
Starting Thread - 2
Counter --- 5
Counter --- 5
Counter --- 4
Counter --- 4
Counter --- 3
Counter --- 3
Counter --- 2
Counter --- 2
Counter --- 1
Counter --- 1
Thread Thread - 1 exiting.
Thread Thread - 2 exiting.
具有静态同步的多线程
这里是一个相同例子的变体,它按顺序打印计数器值,并且每次运行时都会产生相同的结果。这次我们在方法上放置了 synchronized
关键字,使得在方法执行期间整个方法是按照对象锁定的。
具有静态同步的多线程示例
package com.tutorialspoint;
class PrintDemo {
public static synchronized void printCount() {
try {
for(int i = 5; i > 0; i--) {
Thread.sleep(50);
System.out.println("Counter --- " + i );
}
} catch (Exception e) {
System.out.println("Thread interrupted.");
}
}
}
class ThreadDemo extends Thread {
private Thread t;
private String threadName;
ThreadDemo( String name) {
threadName = name;
}
public void run() {
PrintDemo.printCount();
System.out.println("Thread " + threadName + " exiting.");
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
public class TestThread {
public static void main(String args[]) {
ThreadDemo t1 = new ThreadDemo( "Thread - 1 " );
ThreadDemo t2 = new ThreadDemo( "Thread - 2 " );
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch ( Exception e) {
System.out.println("Interrupted");
}
}
}
输出
每次运行此程序都会产生相同的结果:
Starting Thread - 1
Starting Thread - 2
Counter --- 5
Counter --- 4
Counter --- 3
Counter --- 2
Counter --- 1
Thread Thread - 1 exiting.
Counter --- 5
Counter --- 4
Counter --- 3
Counter --- 2
Counter --- 1
Thread Thread - 2 exiting.