本来想把每天看书的心得写到每天的blog中,不过后来想想这种散乱的东西还是写到一起吧。
1.有关join()方法:join()的作用等同于sleep()和isAlive()的结合使用。
用join():把线程A连接(join)到当前线程,然后当前线程将保持sleep,一直到线程A not alive。
用sleep()和isAlive():while(A.isAlive()){thread.sleep(time)};用这个方法比较消耗cpu,并且时间上比用join()浪费。因为当前线程要经过time以后才会去检查A的活动性,有可能那时候A早就stop了。
引用java threads(2e):
When the join() method is called, the current thread will simply wait until the thread it is joining with is no longer alive.
2.别把join()和isAlive()用于当前线程。
引用java threads(2e):
The concept of a thread calling the isAlive() or the join() method on itself does not make sense.
3.补充一个东西(和线程无关):
看以下代码:
public class Test{
public static void main(String[] args) {
StringChange sc = new StringChange();
String str = "hello";
sc.change(str);
System.out.println("outer:" + str);
}
}
class StringChange {
public StringChange() {
}
public void change(String s) {
s += "world";
System.out.println("inner:" + s);
}
}
类似的代码在网上很多,这里有两个问题一个是java中参数传递的问题;另一个是当参数为String的reference时的传递问题。
首先一点,java中是不存在传引用的说法的,都是传值,只不过当参数为基本类型时,传递的是该参数本身,而当参数为对象的reference时,传递的是该reference的地址值,所以,如果传基本类型,那么在执行change之后,main中的基本类型的值没有变化,但是如果传的是reference的话,就会改变main中的对象(也就是改变对象的属性值)。
第二点,因为String对象是个特殊的对象,他一旦生成后,值就不可再变,因此当执行类似于 s += "world";的代码时,其实是生成了另外一个sTemp,而且打印的也是该sTemp,当change返回时,sTemp消失,而s本身没有变化。
敲得我都累啊。呵呵,这个问题很基本,网上也很多介绍,不过说法很多,其中的错误也不少,不知道我这里说清楚没。哈,自己看懂就OK啦。
言归正传,下面继续thread的学习。
4.有关activeCount()和enumerate(Thread[] tarray):
activeCount()是返回当前线程的线程组中活动线程的数目,而enumerate(Thread[] tarray)则是把当前线程的线程组及其子组中的每一个活动线程复制到指定的数组中。
可以结合这两个方法,根据当前线程的线程组中的活动线程的数目,创建一个数组,并把当前线程的线程组的每一个活动线程复制到该数组。
不过这里有个疑问--activeCount()返回的数据中,包括当前线程的线程组的子组吗?待我再研究研究。。
引用java threads(2e):
A thread reference first appears in the thread array returned by the enumerate() method, and is counted by the activeCount() method, when the thread object is first constructed and not when the thread is started.
The thread is removed from the thread array either when the thread is stopped or when the run() method has completed.
5.有关thread的restart:
根据java threads(2e)的描述,一个thread对象的不能够restart。参考下面的代码:
import java.applet.Applet;
public class Animate extends Applet {
TimerThread t;
public void start() {
if (t == null)
t = new TimerThread(this, 500);
t.start();
}
public void stop() {
t.shouldRun = false;
try {
t.join();
} catch (InterruptedException e) {}
// t = null;
}
}
以上代码不能实现t的restart。
引用java threads(2e):
when we try to restart the thread by calling the TimerThread's start() method, nothing happens. The start() method won'treturn an exception condition, but the run() method also won't be called. The isAlive() method also won't return true.
---第一天写blog,也是刚开始学习threads---就当留个记号,同时鼓励自己。
5.先突出重点,把我要引用的话写出来:
引用java threads(2e):
Since there is only one object lock for each instance of the class, the lock that freeBusyFlag() will try to grab is the same lock tryGetBusyFlag() will grab.
这两天看书一直有个疑问,在以下代码中:
public class BusyFlag {
protected Thread busyflag = null;
public void getBusyFlag() {
while (tryGetBusyFlag() == false) {
try {
Thread.sleep(100);
} catch (Exception e) {}
}
}
public synchronized boolean tryGetBusyFlag() {
if (busyflag == null) {
busyflag = Thread.currentThread();
return true;
}
return false;
}
public synchronized void freeBusyFlag() {
if (busyflag == Thread.currentThread()) {
busyflag = null;
}
}
}
是不是应该把tryGetBusyFlag()和freeBusyFlag()放到同一个synchronized定义的范围呢,呵呵,上面那句话把我一下点醒了。
嗯,回味无穷,这是不是算是初学者在学习过程中的一种快乐呢?!
----今天心情不错
6.两段代码:
(1)public class BusyFlag {
protected Thread busyflag = null;
public void getBusyFlag() {
while (tryGetBusyFlag() == false) {
try {
Thread.sleep(100);
} catch (Exception e) {}
}
}
public synchronized boolean tryGetBusyFlag() {
if (busyflag == null) {
busyflag = Thread.currentThread();
return true;
}
return false;
}
public synchronized void freeBusyFlag() {
if (busyflag == Thread.currentThread()) {
busyflag = null;
}
}
}
(2)public class BusyFlag {
protected Thread busyflag = null;
public synchronized void getBusyFlag() {
while (true) {
if (busyflag == null) {
busyflag = Thread.currentThread();
break;
}
try {
Thread.sleep(100);
} catch (Exception e) {}
}
}
public synchronized void freeBusyFlag() {
if (busyflag == Thread.currentThread()) {
busyflag = null;
}
}
}
第二段代码会导致死锁,第一段不会。
把第二段代码的改成以下就可以了:
public void getBusyFlag() {
while (true) {
synchronized(this) {
if (busyflag == null) {
busyflag = Thread.currentThread();
break;
}
}
try {
Thread.sleep(100);
} catch (Exception e) {}
}
}