并发和并行是即相似又有区别:
线程是指进程中的一个执行任务(控制单元),一个进程可以同时并发运行多个线程,如:多线程下载软件。
一个进程至少有一个线程,为了提高效率,可以在一个进程中开启多个执行任务,即多线程。
多进程:操作系统中同时运行的多个程序。
多线程:在同一个进程中同时运行的多个任务。
我们查看Windows环境下的任务管理器:
在操作系统中允许多个任务,每一个任务就是一个进程,每一个进程也可以同时执行多个任务,每一个任务就是线程。
多线程作为一种多任务、并发的工作方式,当然有其存在优势:
import java.io.IOException;
//如何用java语言开启一个进程
public class ProcessDemo {
    public static void main(String[] args) throws IOException{
        //方式一:使用Runtime的exec方法
        Runtime.getRuntime().exec("notepad");
        //方式二:使用ProcessBuilder类中的start方法
        ProcessBuilder pb = new ProcessBuilder("notepad");
        pb.start();
    }
}
2.覆写run方法,将线程运行的代码存放在run中;
3.创建自定义类的对象,即线程对象;
4.调用线程对象的start方法,启动线程。
package thread_create;
//继承方式 创建和启动线程
class MusicThread extends Thread{      //MusicThread是线程子类
    public void run() {               //子类必须重写run()方法
        for(int i = 0 ;i < 50;i++)
        {
            System.out.println("听音乐"+i);
        }
    }
    
}
public class ExtendsThreadDemo {
    public static void main(String[] args){
        for(int i = 0 ;i < 50;i++)
        {
            System.out.println("玩游戏"+i);
            if( i == 10){
                MusicThread t = new MusicThread();  //创建线程子类的实例
                t.start(); //底层也调用了run();  启动线程
            }
        }
            
    }
}
1.自定义类实现Runnable接口;
2.覆写run方法,线程运行的代码存放在run中;
3.通过Thread类创建线程对象,并将实现了Runnable接口的实现类对象作为参数传递给Thread类的构造器。
4.Thread类对象调用start方法,启动线程。
class MusicRunnable implements java.lang.Runnable{         //注意MusicRunnable类不是线程类或者线程子类
    public void run() {                                    //接口的实现必须覆盖方法。               
        for(int i = 0 ;i < 50;i++)
        {
            System.out.println("听音乐"+i);
        }
    }
}
public class ImplementsRunnableDemo {
    public static void main(String[] args){
        for(int i = 0 ;i < 50;i++)
        {
            System.out.println("玩游戏"+i);
            if( i == 10){
                Runnable t = new MusicRunnable();        //启动线程必须用线程类对象调用start();
                new Thread(t).start();             //类Thread的一个构造器中Thread(Runnable target)分配新的 Thread 对象。
            }
        }
    }
}
1、继承Thread类
/**
 *  案例:存在50个苹果,现在有请三个童鞋(小A,小B,小C)上台表演吃苹果.
 *      因为A,B,C三个人可以同时吃苹果,此时得使用多线程技术来实现这个案例.
 *
 *       此处程序不合理,ABC每个线程都执行50次,即ABC每个人都吃一次编号50的苹果
 */
class Person extends Thread{
    private  int num= 50;
    Person(String name){
        super(name);
    }
    public void run() {
        for(int i = 0;i < 50;i++){
        if(num > 0) 
        System.out.println(super.getName()+"吃了第"+num--+"个苹果");
        }
    }   
}
//使用继承Thread的方式创建线程
public class ExtendsDemo {
    public static void main(String[] args){
        Person p1 = new Person("A");
        p1.start();
        Person p2 = new Person("B");
        p2.start();
        Person p3 = new Person("C");
        p3.start();
    }
}
2、实现Runnable接口
class Apple implements Runnable{
    private int num = 50;
    public void run(){
        for(int i = 0; i< 50 ;i++){
            if(num > 0){
                System.out.println(Thread.currentThread().getName()+"吃了第"+num--+"个苹果");
            }//Thread.currentThread()   返回对当前正在执行的线程对象的引用。
        }
    }
}
//使用实现Runnable接口的方式,这种方法可以解决此问题
public class ImplementsDemo {
    public static void main(String[] args){
        Runnable r = new Apple();
        new Thread(r,"A").start();
        new Thread(r,"B").start();
        new Thread(r,"C").start();
    }
}
对比
继承方式:
实现方式
原文:https://www.cnblogs.com/tfper/p/9689916.html