OCJP之MultipleThread 更新中...

Synchronized考得比较多,边学边总结。错误之处,请不吝赐教

1 Synchronized

1) 锁的作用域

    每个class和instance都有一把属于自己的锁,当有synchronized关键字时,要执行方法时,必须拿到相应的锁。

    class:  当synchronized被static修饰时,它是锁定类

    instance:  当synchronized修饰方法时,它锁定此方法的所在的对象。如果有多个方法被synchronized修饰,那么一个synchronized执时,其它的synchronized方法全部阻塞,等待被锁定的对象释放。

例如:

     public class StaticSynchronized implements Runnable {
         static int id = 1;
        
         public void run() {
         try {
             id = 1 - id;
             if(id == 0) { pick(); }
             else { release(); }
             }catch(Exception e) { }
         }
        
         //static synchronized锁定类;
         private static synchronized void pick() throws Exception {
             System.out.print("P "); System.out.print("Q ");
         }
        
         //synchronized锁定对象;
         private synchronized void release() throws Exception {
             System.out.print("R "); System.out.print("S ");
         }
        
         public static void main(String[] args) {
             StaticSynchronized st = new StaticSynchronized();
             new Thread(st).start();
              new Thread(st).start();
         }
        
     }



Possible Output:


// all combination that satisfies the following rules: 1) P is ahead of Q 2) R is ahead of S 3) PQ and RS will be printed only once

P Q R S

P R S Q

P R Q S

.....

解析:

虽然有2个synchronized的方法,但一个锁定类;一个锁定对象,毫不冲突

例如二:


今天看到群里有人说了个小笑话,说他去超市,有个小孩当着他面问妈妈,这个人是男是女?

我一直在找个原型,模拟一些多线程实例,就这个小笑话,模拟一下类级锁吧。

package com.ocjp.testThread;
/*
 * static synchronized method, it will lock the class;
 */
public class TestSynchoronzied{
	public static void main(String[] args) {
		MyThread t1 = new MyThread();
		t1.p = new Person(1,"adult");
		MyThread t2 = new MyThread();
		t2.p = new Person(2,"kid");
		System.out.println("test synchronized to lock an object");
		
		t1.start(); //t1 will call MyThread.shopping();
		//isGoodPerson() cannot be invoked till shopping() is fully completed;
		//Though shopping() even sleep(1000) during running; but this method will hold the class lock; Other methods who need the same class lock have to wait;
		t2.start(); //t2 will call MyThread.isGoodPerson();
	}

}

class MyThread extends Thread {

	Person p;
	
	public void run(){
		if(p.getPid()==1){
			shopping(p);
		}else{
			isGoodPerson(p);
		}
	}
	
	static synchronized void isGoodPerson(Person p){
//	static synchronized void isGoodPerson(){
		System.out.println("kid asks his mom: is this Person good or bad?");
			try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("Mom answered: I think he is bad");
	}
	
	static synchronized void shopping(Person p){
		System.out.println("Person is shopping");
	}
	
}

class Person{
	
	private int pid;
	private String pname;
	
//	getter & setter(); constructor();
	public int getPid() {
		return pid;
	}

	public void setId(int id) {
		this.pid = id;
	}

	public String getPname() {
		return pname;
	}

	public void setPname(String name) {
		this.pname = name;
	}

	
	public Person(int id, String name) {
		super();
		this.pid = id;
		this.pname = name;
	}
	
	public Person(){}
	
}


Output:

kid asks his mom: is this Person good or bad? //converstation between mom and kid cannot be interrupted;
Mom answered: I think he is bad
Person is shopping


or:

Person is shopping
kid asks his mom: is this Person good or bad?
Mom answered: I think he is bad


2 多线程中阻塞状态的方法

    sleep(); 静态方法,无论哪个对象调,都相当于Thread.sleep(),让当前线程处于睡眠状态,让出CPU使用权,但不交出锁...有异常

    yield(); 调用它的线程,让出一次CPU使用权,基本不影响时间片的分配。。。

    join(); 调用它的线程优先执行,其它线程处于阻塞状态,相当于变成单线程;如果传了参数,那么在指定的时间范围内,如果调用它的线程还活着,就进入多线线程状态;


模拟代码:

package com.ocjp.testThread;

public class TestJoin {

	public static void main(String[] args) {
		Reader r = new Reader();
		Thread t = new Thread(r);
		t.start();
//		join()是给调用它的线程更多时间片,让别的线程排在它后面执行,相当于变成了单线程;
//		join()有异常,要处理;
		try {
//			给t分配了0.1秒的时间,去完成;0.1秒后又恢复多线程;
			t.join(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		for(int i=0;i<100;i++){
			System.out.println(Thread.currentThread().getName());
		}
	}
}

class Reader implements Runnable{

	@Override
	public void run() {
		for(int i=0;i<100;i++){
			System.out.println(Thread.currentThread().getName());
//			try {
//				Thread.sleep(100);
//			} catch (InterruptedException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
		}
	}
	
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值