线程相对进程来说占用更少的资源,它们共享内存,共享资源,但线程带来的程序的复杂性,尤其是安全性和生命期问题.因为不同的线程共享相同的内存,一个线程完全有可能破坏另一个线程使用使用的变量和数据结构.如果一个程序在没有内存保护机制的操作系统中运行,也会以类似的方式破坏整个系统.因此,不同线程必须非常注意当时使用的资源.进程是拷贝一份资源的副本,而内存是共享一片内存,所以线程得更注意同步的问题,同时得避免死锁.
1.返回线程中的信息
从结束的线程中获取信息,这是多线程编程中最常见的错误理解之一.run(),start()方法不返回任何值,示例代码如下:
ReturnDigest.java
public class ReturnDigest extends Thread
... {
String a = "000" ;
public void run()
...{
a = "int run";
}
public String geta()
...{
return a;
}
}
ReturnDigestMain.java
public class ReturnDigestMain
... {
/** *//**
* @param args
*/
public static void main(String[] args)
...{
// TODO Auto-generated method stub
ReturnDigest returndigest = new ReturnDigest();
returndigest.start();
System.out.println(returndigest.geta()) ;
}
}
会输出什么结果呢,会输出"in run"么,答案是"000",因为在调用returngest.gata()时,returndigest线程已经结束了,但也有可能是"in run",但这种可能性比较小.
2.同步块
只要是多线程共享资源,都必须考虑同步.这些线程可能是相同Thread子类的实例,或者使用了相同的Runnable,也可能是完全不同的类的实例.关键在于这些线程所共享的资源,而不是这些线程发球哪个表.在Java中,所有资源都用某个类的实例对象表示.只有在两个线程都拥有相同对象的引用时,同步才成为问题.同步使得VM的性能下降,也大增加了死锁的机会,也可能无法保护真正需要保护的对象
3.休眠
进入休眠的线程还拥有它获得的所有锁,因此,其他需要相同锁的线程会阻塞,即使CPU可用,所以要尽量避免在同步方法或块内让线程休眠