线程不是时髦的技术,但是是基本的技术,对于的长远发展,必须要做好这些基本功。
线程就是程序的一条执行线索,运用多线程,可以在程序中有多条执行路线,比如说可以有两个while循环,而没有多线程,这是无法实现的,必须的等到一个while循环结束,才能执行下一个while循环。
线程的创建有两种方式:
-
方法一:(new thread的子类)两件事:创建;启动
- Thread thread=new Thread(){}//创建线程的子类,重写run()方法
- thread.start();//启动线程
Run()内部代码如下:
- public void run() {
- if (target != null) {
- target.run();
- }
- }
代码中的target是这样定义的: private Runnable target;target是一个Runnable对象 ,所以可以把Runnable对象传递给线程Thread,Thread运行的时候就会去找Runnable的run()方法,代码就会运行,在源代码中target是通过init()赋值的。通过上述代码可以理解线程创建的第二个方法:
-
方法二:new Thread(),run()方法放在new Runnable()里面,体现面向对象思想
- Thread thread2=new Thread(new Runnable(){}//在Runnable()放run()方法
- thread2.start();
创建线程的两种方法的代码如下:
- public class TraditionalThread {
- //创建线程的方法一
- public static void main(String[] args) {
- Thread thread=new 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());
- //this代表该run方法所在的对象Thread,this相当于Thread.currentThread()
- System.out.println("2:"+this.getName());//尽管this可以使用,但应该避免,容易混淆
- }
- }
- };
- thread.start();
- //线程创建方法二
- Thread thread2=new Thread(new Runnable(){//Runnable()里边放运行的代码
- @Override //new Runnable()更能体现面向对象的方式
- public void run() {
- while(true){
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- System.out.println("1:"+Thread.currentThread().getName());//当前线程对象
- //这时候不能使用this,因为this在这个时候代表 Runnable(),而它不是线程,
- //是线程要运行代码的宿主
- }
- }
- });
- thread2.start();
- }
- }
运行的结果:
为加深对两种方法创建线程的理解,判断以下的代码执行那一个run()方法:
- public class TraditionalThread {
- //创建线程的方法一
- public static void main(String[] args) {
- Thread thread=new 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());
- //this代表该run方法所在的对象Thread,this相当于Thread.currentThread()
- System.out.println("2:"+this.getName());//尽管this可以使用,但应该避免,容易混淆
- }
- }
- };
- thread.start();
- //线程创建方法二:new Runnable()更能体现面向对象的方式,最好用这种方式
- Thread thread2=new Thread(new Runnable(){//Runnable()里边放运行的代码
- @Override
- public void run() {
- while(true){
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- System.out.println("1:"+Thread.currentThread().getName());//当前线程对象
- //这时候不能使用this,因为this在这个时候代表 Runnable(),而它不是线程,
- //是线程要运行代码的宿主
- }
- }
- });
- thread2.start();
- //判断以下代码执行哪一个run()方法
- //代码结构new Thread(runnable.run){run}.start(),判断是运行runnable.run方法还是{run}方法
- 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());
- }
- }
- }
- ){//new Thread(){}.start()
- public void run() {
- while(true){
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("thread :" + Thread.currentThread().getName());
- }
- }
- }.start();
- }
- }
分析:用面向对象的思想思考:Thread启动以后,会用当前对象的run方法,即会去运行这个{run}里面的run()方法,当该方法不存在时才会去运行runnable.run,即runnable里边的run()方法,run方法把runnable.run方法盖掉了。
运行结果部分(死循环)截图:
下面是关于线程一点常识性的知识:
1,多线程不会提高程序的运行效率,一般来说反而会使程序更慢,cpu只有一个(现在2核的除外),性能更低,线程之间的切换也会浪费一定的时间,
2,拷贝文件,一次性拷贝更快,而不是一个一个拷贝更快
3,多线程下载提高下载速度,其实并不是自己的计算机速度快了,是抢了服务器的带宽,是这样加速,利用多线程相当于是去抢了别人的资源,让服务器为自己提供更多的服务。