Java中使用synchronized控制线程同步

本文详细介绍了Java线程间通过synchronized关键字控制共享资源访问的方法,包括使用实例及执行结果分析,以及如何实现线程间的互斥访问。

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

Java线程之间控制占用临界资源(共享资源)用的最多就是synchronized,首先获得资源访问权的线程给资源对象加锁,使用完毕以后再释放对象锁。例如打印机的例子:

public class Printer  { 	
	public void printLetters(char c) {
		 for(int i = 0; i<5; i++) {  
		     System.out.print(c);
		     try {
				Thread.sleep(1000);
			} catch (InterruptedException e) { 
				e.printStackTrace();
			}
		 }  
		 System.out.println();
	}
}

 

 主程序测试:

public class Test3 {
	public static void main(String[] args){
		final Printer p = new Printer();
		
		new Thread(){
			public void run(){
				p.printLetters('a');
			}
		}.start();
		
		new Thread(){
			public void run(){
				p.printLetters('b');
			}
		}.start();		
		
	}
}

执行结果为:

abbaababab

 这样使用毫无疑问,打印的a和b会混杂在一起,因为没有加同步控制,两个线程可以任意使用打印机对象。解决办法就是在Printer类的printLetters方法前面加上synchronized关键字。加上以后某个线程会等待先占用打印机的线程使用完毕释放对象锁以后才能得到打印权。加上synchronized关键字以后的执行结果为:

aaaaa
bbbbb

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

好了,比如打印机还有别的功能,看下面的例子:

public class Printer  { 	
	synchronized public void printBigFile(){
		System.out.println(Thread.currentThread().getName()+"打印大文件....");
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) { 
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName() + "打印大文件结束。。。");
	}
	
//	public void anotherFunction() {
//		System.out.println("另外的非打印功能");
//	}
	
	synchronized public void printLetters(char c) {
		 for(int i = 0; i<5; i++) {  
		     System.out.print(c);
		     try {
				Thread.sleep(1000);
			} catch (InterruptedException e) { 
				e.printStackTrace();
			}
		 }  
		 System.out.println();
	}
}

 主程序测试为:

public class Test3 {
	public static void main(String[] args){
		final Printer p = new Printer();
		
		new Thread(){
			public void run(){
				p.printLetters('a');
			}
		}.start();
		
		new Thread(){
			public void run(){
				p.printLetters('b');
			}
		}.start();
		////////////////////////////////////////////////////
		new Thread(){
			public void run(){
				p.printBigFile();
			}
		}.start();
		
		new Thread(){
			public void run(){
				p.printBigFile();
			}
		}.start();
	
//		Thread.sleep(2000);
//		p.anotherFunction();
	}
}

 执行结果为:

aaaaa
Thread-3打印大文件....
Thread-3打印大文件结束。。。
Thread-2打印大文件....
Thread-2打印大文件结束。。。
bbbbb

 可以看到printBigFile和printLetters之间也互斥了(它们也不能同时执行),正如上面所说的synchronized关键字锁住的是对象,而不是某个方法或者代码段。

再看上面两段代码中注释掉的部分,Printer类中注释掉的anotherFunction方法,以及在主函数中调用anotherFunction,因为anotherFunction没有加synchronized修饰,所以大概也能知道执行结果了,它打印的东西会夹在其它打印内容的中间,anotherFunction方法随时可以被任何线程同时执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值