Java多线程学习(三)

1.多线程同步代码块

1.什么情况下需要同步

(1)当多线程并发,有多段代码同时执行时,希望某一段代码执行过程中CPU不切换到其他的线程上工作,此时需要同步

(2)如果两段代码是同步的,那么同一时间只能执行一段代码,在一段代码执行完成前,CPU不会去执行另一段代码

2.同步代码块

使用synchronized关键字加上一个锁对象来定义一段代码,多个同步代码块如果使用相同的锁对象,那么他们就是同步的

3.案例

package javastudy01;

public class printer {
	
	//目标是实现输出我是胡博士 和 同步代码块 ,分开输出,但由于没有使用同步代码块,会产生一下运行结果,不符合要求
	
	public void printer1(){
		System.out.print("我");
		System.out.print("是");
		System.out.print("胡");
		System.out.print("博");
		System.out.print("士\n");
	}
	
	public void printer2(){
		System.out.print("同");
		System.out.print("步");
		System.out.print("代");
		System.out.print("码");
		System.out.print("块\n");
	}
	
	
	
	
	

	public static void main(String[] args) {
		Thread t1 = new Thread(){
			
			public void run(){
				for(int i=0 ;i<=30;i++){
				new printer().printer1();
				}
			}
			
			
		};
		
		Thread t2 = new Thread(){
			
			public void run(){
				for(int i=0 ;i<=30;i++){
				new printer().printer2();
			}
			}
			
		};
		
		t1.start();
		t2.start();
	}

}

运行结果

 很明显,线程没有按照我们预期的方式去运行

再给出同步代码块:

package javastudy01;

public class printer {
	
	//目标是实现输出我是胡博士 和 同步代码块 ,分开输出,但由于没有使用同步代码块,会产生一下运行结果,不符合要求
	
	Demo d = new Demo();
	public void printer1(){
		synchronized(d){   //多对象可以任意,但不能填入 new Demo()匿名对象,因为匿名对象产生的不是同一个对象
		System.out.print("我");
		System.out.print("是");
		System.out.print("胡");
		System.out.print("博");
		System.out.print("士\n");
		}
	}
	//  Demo  a = new Demo(); //此处的锁对象相同,表示是同步的填入a不起作用
	public void printer2(){
		synchronized(d){
		System.out.print("同");
		System.out.print("步");
		System.out.print("代");
		System.out.print("码");
		System.out.print("块\n");
		}
	}
	
	
	
	
	

	public static void main(String[] args) {
		
		printer p = new printer();
		
		Thread t1 = new Thread(){
			
			public void run(){
				for(int i=0 ;i<=100;i++){
				p.printer1();  //注意:这里不能使用new printer()代替P 如果使用与下面的t2中的p就不是同一个对象,也无法实现输出要求
				 
				}
			}
			
			
		};
		
		Thread t2 = new Thread(){
			
			public void run(){
				for(int i=0 ;i<=100;i++){
				p.printer2();
			}
			}
			
		};
		
		t1.start();
		t2.start();
	}

}


class Demo {
	
}

运行结果

2.同步方法

实现:

public synchronized void printer(){

}

同步方法只需要在方法前加上关键字即可实现

1.非静态方法的锁对象是this

2.静态方法的多对象是字节码对象(printer.class)

因为static 静态优先于对象存在,不能定义this.super,且在创建对象时静态方法才有值

静态方法随类加载而加载

猜你喜欢

转载自blog.csdn.net/watsonliuwho/article/details/82588447