java多线程基础值对象和变量的并发访问之synchronized(二)

本文深入探讨了Java中synchronized关键字的使用方式及其对线程同步的影响,包括静态方法同步、对象级锁、死锁形成原因及内置类同步等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

静态同步synchronized方法和synchronized(class) 同步块

    synchronized加到静态方法上,是给class类上锁,而synchronized关键字加到非static静态方法上是给对象上锁。
public class Service {
	synchronized public static void printA(){
		System.out.println("线程"+Thread.currentThread().getName()+"在"+
	System.currentTimeMillis()+"进入A");
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("线程"+Thread.currentThread().getName()+"在"+
				System.currentTimeMillis()+"进入A");
	}
	
	synchronized public static void printB(){
		System.out.println("线程"+Thread.currentThread().getName()+"在"+
	System.currentTimeMillis()+"进入B");
		System.out.println("线程"+Thread.currentThread().getName()+"在"+
				System.currentTimeMillis()+"进入B");
	}
	
	synchronized public void printC(){
		System.out.println("线程"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入C");
		System.out.println("线程"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入C");
	}
}
线程A,线程B,线程C执行方法A,B,C 结果:
方法A和方法B同步执行,方法C由于是上对象的锁和其他线程是异步执行的

synchronized(class){}同步块,也是获取class对象的锁,不同线程执行a,b方法,也会是同步的效果
public class Service {
	 public  void printA(){
		 synchronized (Service.class) {
			 System.out.println("线程"+Thread.currentThread().getName()+"在"+
						System.currentTimeMillis()+"进入A");
							try {
								Thread.sleep(1000);
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
							System.out.println("线程"+Thread.currentThread().getName()+"在"+
									System.currentTimeMillis()+"进入A");
		}
		
	}
	
	 public  void printB(){
		synchronized (Service.class) {
			System.out.println("线程"+Thread.currentThread().getName()+"在"+
					System.currentTimeMillis()+"进入B");
						System.out.println("线程"+Thread.currentThread().getName()+"在"+
								System.currentTimeMillis()+"进入B");
		}
	}
}

synchronized使用过程中需要注意String常量池的特性

string做为锁对象,“AA”和后面的AA是由于字符串常量池特性,是同一个对象,因此下面的程序是同步执行,
如果改为new object(),每次调用方法时候是不同的锁对象,结果就会是异步执行
public class Service {
	 public void print(String stringparam){
		 synchronized (stringparam) {
			 while(true){
				 System.out.println(Thread.currentThread().getName());
				 try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			 }
		}
	 }
	 public static void main(String[] args) {
		 final Service service = new Service();
		 Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				service.print("AA");
			}
		},"A");
		 
		 Thread t2 = new Thread(new Runnable() {
				@Override
				public void run() {
					service.print("AA");
				}
			},"B");
		 
		 t1.start();t2.start();
	}
}

  多线程的死锁形成的原因:
1. 两个线程相互等待对方释放锁
2. 一个线程持有锁,由于死循环没有释放,导致另一个线程无限等待
/**
 * 死锁,两个线程相互等待锁,造成死锁
 * @author zhouy
 *
 */
public class DeadThread {
	public Object lock1 = new Object();
	public Object lock2 = new Object();
	public void deadLock(){
		Thread t1 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				synchronized (lock1) {
					System.out.println("t1获取到lock1的锁");
					try {
						Thread.currentThread().sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					synchronized (lock2) {
						System.out.println("t1获取到lock2的锁");
					}
				}
			}
		});
		
		Thread t2 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				synchronized (lock2) {
					synchronized (lock1) {
						System.out.println("t2获取到lock1的锁");
					}
				}
			}
		});
		t1.start();
		t2.start();
	}
	public static void main(String[] args) {
		new DeadThread().deadLock();
	}
}

内置类同步
内置类的同步也是一样的,只要关注锁对象是否相同,锁对象相同的,线程就是同步执行的,否则就是异步,
而且,只要锁对象不变,锁对象的属性改变,也不会影响线程同步
public class Service {
	synchronized public void testMethod(UserInfo user){
		synchronized (user) {
			user.setUsername("abcde");
			System.out.println(Thread.currentThread().getName());
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+" end! "+System.currentTimeMillis());
		}
	}
	synchronized public void test(UserInfo user){
		synchronized (user) {
			user.setPassword("abcde");
			System.out.println(Thread.currentThread().getName());
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+" end! "+System.currentTimeMillis());
		}
	}
	public static void main(String[] args) {
		final Service service = new Service();
		final UserInfo user = new UserInfo();//final修饰 引用不可变,对象还是可变的
		
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				service.testMethod(user);
			}
		}, "A");
		t.start();
		service.test(user);
		
	}
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值