SCJP笔记整理(九)
说明:这是2007年复习SCJP期间的学习笔记(JavaSE 5.0),有部分遗失。现在整理一下发到Blog上,一方面做个备份,另一方面分享出来,希望对需要的人有用。
------------------------
?
}
public void run(String s){ //
}
执行将不会用不同的调用堆栈在一个新的执行线程中发生,它只发生在于你发出调用代码相同的调用堆栈中。
Thread t3=new Thread(r);
? String s = Thread.getcurrentThread().getName();
? System.out.println(s);
}
}
public voiddoStuff(){
???? synchronized(this){
???? System.out.println(“this”);
}
}
????? return count;
}
或使用同步块:
public static int getCount(int count){
?????synchronized(MyClass.class){
return count;
}
}
如果它们使用两个不同的实例进行调用,将调用两个锁,这两个锁互不干扰。
调用同一个类中的静态方法的线程将始终彼此阻塞(即使是不同对象)—它们都锁定在相同的Class实例上。
静态同步方法和非静态同步方法将永远不会彼此阻塞。
同数据的线程却可以彼此忽略。
静态数据中的可交换数据,确保尝试访问数据的任何两个线程将不会同时访问。
静态字段的访问应该通过静态同步方法完成,访问非静态字段应该通过非静态同步方法完成。
?? public static voidmain(String[] s){
?? ThreadB b=new ThreadB();
?? b.start();
??
?? synchronized(b){? //拥有b对象的锁,以调用wait()方法。
?? try{
????? b.wait();?? //等待,释放该对象的锁。
}catch(InterruptedExceptione){
?? System.out.println(“exc”);
}
}
}
}
?
class ThreadB {
?? int total;
?? public void run(){
?????? synchronized(this){ //获得对象锁,以调用notify()。
????????? for(inti=0;i<100;i++){
? total += i;
}
notify();? //通知ThreadA进入可运行态。
}
}
}
29、在对象上调用wait()方法时,执行该代码的线程立即放弃它在对象上的锁。当调用notify()时,并不意味着这时线程会放弃其锁,如果线程仍旧在完成同步代码,则线程在移出同步代码之前不会放弃锁,所以只调用notify()不意味着这时该锁将变得可用。
30、可以使用notifyAll()让所有线程冲出等待区,返回可运行状态。多个线程等待一个对象,使用notify()将只影响其中一个,具体哪个将由JVM决定。
31、放入某种循环中,该循环检查某种条件表达式,并且只有在你正在等待的事情还没有发生的情况下,才继续等待。
32、还有一种称为自发醒来的情形,存在于下列场合:线程可能醒来,即使代码没有调用notify()或notifyAll()。将wait()放入while循环,并且重新检查表示我们正在等待的事情的条件。我们确保不管因为什么原因醒来,当且仅当我们正在等待的事情还没有发生,将重新进入wait()。
33、要点:当使用wait() \ notify() \ notifyAll()时,几乎总有一个while循环包围着wait(),以便检查条件,并强制连续等待,直到条件满足为止。
34、Object类----wait() \ notify() \ notifyAll().
??? Thread类----start() \ join() \ yield():static\ sleep():static
??? Runnable类----run().
?