首页 > 代码库 > (CZ深入浅出Java基础)线程笔记

(CZ深入浅出Java基础)线程笔记

 

一.线程的引入

1.多线程概述

1.1.进程

a.正在运行的程序,是系统进行资源分类和调用的独立单位。

b.每个进程都有它自己的内存空间和系统资源。

1.2.线程

a.是进程中的单个顺序控制流,是一条执行路径。

b.一个进程如果只有一条路径,则称为单线程程序。

c.一个进程如果有多条执行路径,则称为多线程程序。

1.3.小结

线程多的进程抢到CPU执行权的概率大,但是仍具有随机性。

2.Java程序运行原理

2.1.Java运行

Java命令会启动Java虚拟机,启动JVM,等于启动了一个应用程序,也就是启动了一个进程。该进程会自动启动一个“主线程”,然后主线程去调用某个类的main方法。

3.并发和并行

3.1.并发

物理上的同时发生,并发是在同一个时间点上同时发生。

3.2.并行

逻辑上的同时发生,并行是在同一个时间段上同时发生。

二.线程的使用

1.多线程的使用举例

 1 public class Demo {
 2 
 3     public static void main(String[] args) {
 4         // TODO Auto-generated method stub
 5         MyThread my1=new MyThread();
 6         MyThread my2=new MyThread();
 7         my1.start();
 8         my2.start();
 9     }
10 
11 }
12 
13 class MyThread extends Thread{
14     @Override
15     public void run() {
16         // TODO Auto-generated method stub
17         for(int i=0;i<1000;i++){
18             System.out.println(i);
19         }
20     }
21 }

2.线程的基本使用

2.1.获取名称

 1 public class Demo {
 2 
 3     public static void main(String[] args) {
 4         // TODO Auto-generated method stub
 5         MyThread my1 = new MyThread();
 6         MyThread my2 = new MyThread();
 7         my1.start();
 8         my2.start();
 9     }
10 
11 }
12 
13 class MyThread extends Thread {
14     @Override
15     public void run() {
16         // TODO Auto-generated method stub
17         for (int i = 0; i < 1000; i++) {
18             System.out.println(getName() + ":" + i);
19         }
20     }
21 }

获取当前进程对象:

public class Demo {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Thread main_thread = Thread.currentThread();
        System.out.println(main_thread.getName());
    }
}

2.2.设置线程名称

可以通过构造函数,也可以通过setName方法

 1 public class Demo {
 2 
 3     public static void main(String[] args) {
 4         // TODO Auto-generated method stub
 5 //        MyThread my1 = new MyThread();
 6 //        MyThread my2 = new MyThread();
 7 //        my1.setName("my1");
 8 //        my2.setName("my2");
 9         
10         MyThread my1 = new MyThread("my1");
11         MyThread my2 = new MyThread("my2");
12         
13         my1.start();
14         my2.start();
15     }
16 
17 }
18 
19 class MyThread extends Thread {
20     @Override
21     public void run() {
22         // TODO Auto-generated method stub
23         for (int i = 0; i < 1000; i++) {
24             System.out.println(getName() + ":" + i);
25         }
26     }
27     
28     public MyThread(){
29         super();
30     }
31     
32     public MyThread(String name){
33         super(name);
34     }
35 }

2.3.线程调度

设置优先级,但是线程优先级也只是标识线程获得CPU控制权的几率高。

 1 public class Demo {
 2 
 3     public static void main(String[] args) {
 4         // TODO Auto-generated method stub
 5         
 6         MyThread my1 = new MyThread("my1");
 7         MyThread my2 = new MyThread("my2");
 8         
 9         System.out.println(my1.getName()+"---"+my1.getPriority());
10         System.out.println(my2.getName()+"---"+my2.getPriority());
11         
12         my1.setPriority(1);
13         my2.setPriority(10);
14         
15         my1.start();
16         my2.start();
17     }
18 
19 }
20 
21 class MyThread extends Thread {
22     @Override
23     public void run() {
24         // TODO Auto-generated method stub
25         for (int i = 0; i < 1000; i++) {
26             System.out.println(getName() + ":" + i);
27         }
28     }
29     public MyThread(String name){
30         super(name);
31     }

2.4.线程休眠

 1 public class Demo {
 2 
 3     public static void main(String[] args) {
 4         // TODO Auto-generated method stub
 5         
 6         MyThread my1 = new MyThread("my1");
 7         MyThread my2 = new MyThread("my2");
 8         
 9         my1.start();
10         my2.start();
11     }
12 
13 }
14 
15 class MyThread extends Thread {
16     @Override
17     public void run() {
18         // TODO Auto-generated method stub
19         for (int i = 0; i < 1000; i++) {
20             System.out.println(getName() + ":" + i);
21             try {
22                 Thread.sleep(1000);//这个异常只能try-catch处理,因为父类的run方法没有抛出异常,子类重写方法也不能抛出异常
23             } catch (InterruptedException e) {
24                 // TODO Auto-generated catch block
25                 e.printStackTrace();
26             }
27         }
28     }
29     
30     public MyThread(String name){
31         super(name);
32     }
33 }

  2.5.线程加入

指的是调用join方法的线程执行完了,下面的程序才能执行。

 1 public static void main(String[] args) {
 2         // TODO Auto-generated method stub
 3         
 4         MyThread my1 = new MyThread("my1");
 5         MyThread my2 = new MyThread("my2");
 6         MyThread my3 = new MyThread("my3");
 7         
 8         my1.start();
 9         try {
10             my1.join();
11         } catch (InterruptedException e) {
12             // TODO Auto-generated catch block
13             e.printStackTrace();
14         }
15         my2.start();
16         try {
17             my2.join();
18         } catch (InterruptedException e) {
19             // TODO Auto-generated catch block
20             e.printStackTrace();
21         }
22         my3.start();
23     }

join的用法可以参考:java多线程 join方法以及优先级方法,Java多线程中join方法的理解。

(太长不看版= =:join方法就是要等这个自己这个线程走完了,调用启动自己这个线程的主线程才能继续往下走,其他线程不管,具体的可以试试下面的代码)

 1 public class Demo {
 2 
 3     public static void main(String[] args) {
 4         MyThread my1 = new MyThread("my1");
 5         MyThread my2 = new MyThread("my2");
 6         MyThread my3 = new MyThread("my3");
 7         
 8         my1.start();
 9         my2.start();
10         try {
11             my1.join();
12         } catch (InterruptedException e) {
13             // TODO Auto-generated catch block
14             e.printStackTrace();
15         }
16         for(int i=0;i<10000;i++){
17             System.out.println("main");
18         }
19         my3.start();
20     }
21 }

技术分享大概就这个意思

 

2.6.线程礼让

只能让线程的执行更加和谐,但不能保证绝对谦让。

public class Demo {

    public static void main(String[] args) {
        MyThread my1 = new MyThread("my1");
        MyThread my2 = new MyThread("my2");
        MyThread my3 = new MyThread("my3");

        my1.start();
        my2.start();
        // my3.start();
    }
}

class MyThread extends Thread {
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 1000; i++) {
            System.out.println(getName() + ":" + i);
            Thread.yield();
        }
    }

    public MyThread(String name) {
        super(name);
    }
}

2.7.守护线程

将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。该方法必须在启动线程前调用。该方法首先调用该线程的 checkAccess 方法,且不带任何参数。这可能抛出 SecurityException(在当前线程中)。 

抛出:IllegalThreadStateException - 如果该线程处于活动状态。

    SecurityException - 如果当前线程无法修改该线程。

public class Demo {
    public static void main(String[] args) {
        MyThread my1 = new MyThread("my1");
        MyThread my2 = new MyThread("my2");
        MyThread my3 = new MyThread("my3");
        
        my1.setDaemon(true);
        my2.setDaemon(true);
        my3.setDaemon(true);
        
        my1.start();
        my2.start();
        my3.start();
        
        for(int i=0;i<5;i++){
            System.out.println("main");
        }
    }
}

2.8.中断线程

stop方法已经不建议使用了。然而Interupt方法我也没太搞懂= =

import java.util.Date;

public class Demo {
    public static void main(String[] args) {
        MyThread my1 = new MyThread("my1");
        my1.start();
        try {
            Thread.sleep(3000);
            my1.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.out.println("线程终止");
        }
//        my1.stop();
        
    }
}

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("开始执行:" + new Date());
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            System.out.println("线程终止");
        }
        System.out.println("结束执行:" + new Date());
    }

    public MyThread(String name) {
        super(name);
    }
}

 

2017.4.28


 

(CZ深入浅出Java基础)线程笔记