Java中的静态同步
同步是规范多个线程对任何共享资源的访问的潜力。 Java中的同步对于线程之间的可靠通信至关重要。它是在Java中使用同步关键字实现的。
关于同步的要点
- 它仅适用于对象级别的方法。
- 如果方法或块是同步的,则它需要对象级锁才能开始执行。
- 同步是Java中最危险的词,因为这是导致死锁的唯一原因。
- 在需要时使用同步关键字,并尝试使用同步块。
静态同步
Synchronized 方法可能会失去其获取有序输出的行为。当一个类有更多对象时,它只获取特定实例的锁。为了保持同步行为,我们需要一个类级别的锁,而不是可以通过静态同步实现的实例级别的锁。
静态同步方法也是一种在Java中同步方法的方法,这样没有两个线程可以同时对同步方法进行静态操作。唯一的区别是使用静态同步。我们正在获得一个类级别的锁,这样只有一个线程将对该方法进行操作。线程将获取一个Java类的类级锁,这样只有一个线程可以作用于静态同步方法。
句法:
synchronized static return type class name{}
Note: When a class has both synchronized and static synchronized methods they can run parallelly ,as those two methods require different locks.
让我们假设有 6 个线程。执行顺序将是
线程和类
这里 t1,t2... t6 是线程名称
The complete declarations of methods are:
method1: public static synchronized void method1()
method2: public static synchronized void method2()
method3: public static void method3()
method4: public synchronized int method4()
method5: public String method5()
- t1.method1()在获得 Manager 类的类级别锁定时开始执行。
- t2.method2()等待它的时间开始执行,因为它是一个静态同步方法,它需要一个类级别的锁,因为t1已经获得了类级别的锁,t2必须等到t1执行。
- t3.method2()等待,因为它需要类级别的锁,所以它必须等到 t1 释放锁。
- t4.method3()开始执行,因为它是静态方法,不需要锁
- t5.method4()开始执行,因为它是实例或(普通)级别的同步方法,并且需要对象级别的锁,因此它获得了对象级别的锁。
- t 6.method5()开始执行,因为它是实例方法或普通方法
示例:下面是一个静态同步的多线程示例程序
Java
// Java program of multithreading
// with static synchronized
class Display
{
public static synchronized void wish(String name)
{
for(int i=0;i<3;i++)
{
System.out.print("Good Morning: ");
System.out.println(name);
try{
Thread.sleep(2000);
}
catch(InterruptedException e)
{
}
}
}
}
class MyThread extends Thread{
Display d;
String name;
MyThread(Display d,String name)
{
this.d=d;
this.name=name;
}
public void run()
{
d.wish(name);
}
}
class Main{
public static void main(String arg[])
{
Display d1=new Display();
Display d2=new Display();
MyThread t1=new MyThread(d1,"Dhoni");
MyThread t2=new MyThread(d2,"Yuvaraj");
t1.start();
t2.start();
}
}
Note: Each wish will be printed after a gap of 2000 ms.
输出
First time of execution:
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Yuvaraj
Good Morning: Yuvaraj
Good Morning: Yuvaraj
Second time of execution:
Good Morning: Yuvaraj
Good Morning: Yuvaraj
Good Morning: Yuvaraj
Good Morning: Dhoni
Good Morning: Dhoni
Good Morning: Dhoni
解释:
在上面的程序中,定义了三个类,分别是 Display、MyThread 和 Main,每个类都有——
- class Display:子线程运行所需的代码
- class MyThread:这个类的目的是继承Thread类并分配值名,调用Display类的wish方法
- class Main:是整个程序的主类,它创建了一个子线程
控制流程:
众所周知,程序的执行从 main 方法开始。首先,我们创建两个子线程,并将它们分配给线程的显示对象,在t2.start()之后,会出现三个线程,即(main,t1,t2),执行过程如下。
子线程开始执行t1,由于wish方法是静态同步的,线程t1获得类Display的类级锁,开始执行wish方法。如果下一个线程来了,它必须等到前一个线程的执行才能获得类级别的锁。
Note: We can’t say the exact order of output. As a programmer, we cannot say which thread starts its execution or the order of execution ,they are not in the hands of a programmer it is the job of Thread schedular.
Java中同步和静态同步的区别
Synchronized | Static Synchronized |
---|---|
It requires an object-level lock. | It requires a class-level lock. |
Its method need not be declared static. | Its method needs to be declared static. |
It is used regularly. | It is not used regularly. |
A different instance is created for each object. | Only one instance for the entire program. |