synchronized 关键字用于多线程同步,与多线程的锁的作用类似,可以用来修饰函数或代码块。
1. 修饰函数:表示只对这个函数实行互斥访问
(1)修饰普通函数:锁的是该类的对象实例,该类的不同对象实例的 synchronized方法是不相干扰的。换句话说,线程可以同时访问相同类的不同对象实例中的synchronized方法;注意如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法。
(2)修饰静态函数:锁的是该类,即使是该类的不同对象实例,线程不也可以同时访问相同类的不同对象实例中的synchronized方法
class Test{
public synchronized void method1()
{
int i=1000;
while(i-->0)
System.out.println("method1"+" i="+i);
}
public synchronized void method2()
{
int i=1000;
while(i-->0)
System.out.println("method2"+" j="+i);
}
public static synchronized void method3()
{
int i=1000;
while(i-->0)
System.out.println("method3"+" k="+i);
}
}
public class SynchronizedDemo1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test test = new Test();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
test.method1();
}
}).start();
new Thread(new Runnable() {
public void run()
{
test.method2();
}
}).start();
Test test2 = new Test();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
test.method3();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
test2.method3();
}
}).start();
}
}
2. 修饰代码块:表示只对这个区块的资源实行互斥访问
(1)作用域为当前对象:synchronized(this){},不同线程只能互斥的进入该对象的代码块。注意,当该对象的不同的方法中存在同步块中,虽然这些同步块处在不同的方法中,但由于是同步到同一个对象,所以对它们的方法依然是互斥的。
import java.util.concurrent.TimeUnit;
public class Resource1 {
public void f() {
// other operations should not be locked...
System.out.println(Thread.currentThread().getName()
+ ":not synchronized in f()");
synchronized (this) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+ ":synchronized in f()");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void g() {
// other operations should not be locked...
System.out.println(Thread.currentThread().getName()
+ ":not synchronized in g()");
synchronized (this) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+ ":synchronized in g()");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void h() {
// other operations should not be locked...
System.out.println(Thread.currentThread().getName()
+ ":not synchronized in h()");
synchronized (this) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+ ":synchronized in h()");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
final Resource1 rs = new Resource1();
new Thread() {
public void run() {
rs.f();
}
}.start();
new Thread() {
public void run() {
rs.g();
}
}.start();
rs.h();
}
}
(2)作用域为当前类:synchronized(*.class){},即使是该类的不同对象,不同线程也不能同时访问该类不同对象的同步代码块
package Thread;
import java.util.concurrent.TimeUnit;
public class Resource1 {
public void f() {
System.out.println(Thread.currentThread().getName()
+ ":not synchronized in f()");
synchronized (Resource1.class) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+ ":synchronized in f()");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void g() {
System.out.println(Thread.currentThread().getName()
+ ":not synchronized in g()");
synchronized (Resource1.class) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+ ":synchronized in g()");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
final Resource1 rs = new Resource1();
final Resource1 rs2 = new Resource1();
new Thread() {
public void run() {
rs.f();
}
}.start();
new Thread() {
public void run() {
rs2.g();
}
}.start();
}
}
本文深入解析Java中的synchronized关键字,探讨其在多线程环境下的作用机制,包括如何使用synchronized修饰函数和代码块实现资源互斥访问,以及不同作用域下锁的特性。

被折叠的 条评论
为什么被折叠?



