java synchronized关键字的使用

本文深入解析Java中的synchronized关键字,探讨其在多线程环境下的作用机制,包括如何使用synchronized修饰函数和代码块实现资源互斥访问,以及不同作用域下锁的特性。

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();
    }
}

参考:https://www.cnblogs.com/beiyetengqing/p/6213437.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值