深切怀念传智播客张孝祥老师,特将其代表作——Java并发库视频研读两遍,受益颇丰,记以后阅
01. 传统线程技术回顾
传统是相对于JDK1.5而言的
传统线程技术与JDK1.5的线程并发库
线程就是程序的一条执行线索/线路。
创建线程的两种传统方式
1. 创建Thread的子类,覆盖其中的run方法,运行这个子类的start方法即可开启线程
Thread thread = new Thread()
{ @Override
public void run()
{
while (true)
{
获取当前线程对象 获取线程名字
Thread.currentThread() threadObj.getName()
让线程暂停,休眠,此方法会抛出中断异常InterruptedException
Thread.sleep(毫秒值);
}
}
};
thread.start();
2. 创建Thread时传递一个实现Runnable接口的对象实例
Thread thread =new Thread(new Runnable()
{
public void run()
{}
});
thread.start();
问题:下边的线程运行的是Thread子类中的方法还是实现Runnable接口类的方法
new Thread(
b、传递实现Runnable接口的对象
new Runnable()
{
publicvoid run()
{}
}
){
a、覆盖Thread子类run方法
public void run(){}
}.start();
分析:new Thread(Runnable.run()){run()}.start();
newThread(
newRunnable(){
publicvoid run() {
while(true){
try{
Thread.sleep(500);
}catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("runnable:" + Thread.currentThread().getName());
}
}
}
){
publicvoid run() {
while(true){
try{
Thread.sleep(500);
}catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread:" + Thread.currentThread().getName());
}
}
}.start();
子类run方法实际就是覆盖父类中的run方法,如果覆盖了就用子类的run方法,不会再找Runnable中的run方法了,所以运行的是子类中的run方法
总结:
实现Runnable接口的方式更加体现面向对象的思想,线程是线程,线程的代码是线程的代码,二者虽然联系非常密切,但是也是不同的对象;实现Runnable接口的方式可以让某个类还能继承其它的类。
由Thread类中的run方法源代码中看出,两种传统创建线程的方式都是在调用Thread对象的run方法,如果Thread对象的run方法没有被覆盖,并且像上边的问题那样为Thread对象传递了一个Runnable对象,就会调用Runnable对象的run方法。
多线程并不一定会提高程序的运行效率。举例:一个人同时在三张桌子做馒头【开销】
多线程下载:并不是自己电脑快了,而是抢到更多服务器资源。例:服务器为一个客户分配一个20K的线程下载,你用多个线程,服务器以为是多个用户就分配了多个20K的资源给你。【抢】
public class TraditionalThread { /** * @param args */ public static void main(String[] args) { Thread thread = new Thread(){ @Override public void run() { while(true){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("1:" + Thread.currentThread().getName()); System.out.println("2:" + this.getName()); } } }; thread.start(); Thread thread2 = new Thread(new Runnable(){ @Override public void run() { while(true){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("1:" + Thread.currentThread().getName()); } } }); thread2.start(); new Thread( new Runnable(){ public void run() { while(true){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("runnable :" + Thread.currentThread().getName()); } } } ){ public void run() { while(true){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread :" + Thread.currentThread().getName()); } } }.start(); } }