1 并发和并行

  • 并发:多个事情在同一个时间段内发生,cpu在多个任务中来回快速切换,多个任务高速交替执行
  • 并行:多个事情在同一个时刻发生,多个任务同一时刻在同时进行

2 进程和线程

  • 进程:进程是程序的一次执行过程,是系统运行程序的基本单位,系统运行一个程序即是一个进程从创建、运行到消亡的过程
  • 线程:线程是进程的一个执行单元,一个进程中至少有一个线程。

3 创建线程方式一

新建子类继承Thread类,子类重写run方法,run方法中设置线程任务;创建子类的对象,调用start()方法。

  • 创建线程
public class ThreadCreate1 extends Thread{
    //新建子类继承Thread类,子类重写run方法,run方法中设置线程任务
    //创建子类的对象,调用start()方法。
    @Override
    public void run() {
        for(int i = 0; i < 200; i++){
            System.out.println("thread:" + i);
        }
    }
}
  • 启动线程
public class ThreadTest {
    public static void main(String[] args) {
        ThreadCreate1 thread = new ThreadCreate1();
        thread.start();
        for(int i = 0; i < 200; i++){
            System.out.println("main:" + i);
        }
    }
}

关于线程启动方式:

  • start:使用 start方法启动线程的时候,JVM虚拟机会在内存中给线程分配一个独立的内存空间,有自己的局部变量等
  • run:使用run方法启动线程的时候,就是使用主线程运行,会按照顺序进行调度方法,不会出现抢占资源的情况

4 获取当前线程名称的俩种方式

public class ThreadCreate1 extends Thread{
    //新建子类继承Thread类,子类重写run方法,run方法中设置线程任务
    //创建子类的对象,调用start()方法。
    @Override
    public void run() {
        //第一种:String getName获取线程的名称,如果当前类没有继承Thread类,则不能直接使用getName()
        System.out.println(getName());
        
        //第二种方式获取线程的名称
        System.out.println(Thread.currentThread().getName());
    }
}

5设置线程名称的俩种方式

  • 创建一个带参数的构造方法,把线程名称传递给父类,让父类给子线程起一个名字
public class ThreadCreate1 extends Thread{

    public ThreadCreate1(){}
    //创建一个带参数的构造方法
    public ThreadCreate1(String name){
        super(name); //把线程名称传递给父类,让父类给子线程起一个名字
    }


    //新建子类继承Thread类,子类重写run方法,run方法中设置线程任务
    //创建子类的对象,调用start()方法。
    @Override
    public void run() {
        //第一种:String getName获取线程的名称,如果当前类没有继承Thread类,则不能直接使用getName()
        System.out.println(getName());

        //第二种方式获取线程的名称
        System.out.println(Thread.currentThread().getName());
    }
}

调用:

new ThreadCreate1("小强").start();
  • 第二种命名线程的方式:setName
//第二种创建线程的方法setName()
Thread thread = new ThreadCreate1();
thread.setName("旺财");
thread.start();

6 Sleep

public class ThreadSleep {
    public static void main(String[] args) {
        for(int i = 0; i < 100; i++){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(i+1);
        }
    }

}

7 创建线程的第二种方式-实现Runnable接口,重写run方法

public class ThreadCreate2 implements Runnable{

    @Override
    public void run() {
        for(int i = 0; i < 2000; i++){
            System.out.println("thread:" + i);
        }
    }
}

调用:

public class TestThreadRunnable {
    public static void main(String[] args) {
        //创建线程的具体方法是:新建一个类实现Runnable接口,重写run方法;
        // 创建一个Runnable接口的实现类对象,创建一个Thread对象,构造方法中传递接口实现类对象,调用start方法

        ThreadCreate2 thread = new ThreadCreate2();

        Thread t = new Thread(thread);
        t.start();

        for(int i = 0; i < 200; i ++){
            System.out.println("main" + i);
        }
    }
}

8 继承Thread和实现Runnable接口的区别

实现runnable接口的好处:

-避免了单继承的局限性,因为Java中只能单继承,继承了Thread就不能继承其他类了

9 匿名内部类创建线程

匿名内部类作用:
把子类继承父类,重写父类方法,创建子类对象合作一步完成
把实现类实现接口,重写接口中的方法,创建实现类对象合成一步完成

new Thread(new Runnable() {
@Override
   public void run() {
       for(int i = 0; i < 100; i++){
           System.out.println("thread2" + i);
       }
   }
}).start();