Java多线程学习笔记(一)三种创建线程方式

多线程:
    指一个应用程序中有多条并发执行的线索,每条线索被称作为一个线程,他们交替执行,彼此间可以进行通信。
线程:
    在我们生活中使用的电脑,在电脑中运行的每一个程序其实都是一个进程,一个进程中还可以有多个执行的单元同时运行,这些单元就可以看作程序执行的一条条线索,被称为线程。每一给进程中至少有一个线程在运行。
线程的实现方式:
    第一种:通过继承Thread类实现多线程
实例:

public class Example01 {
    
    
    public static void main(String[] args) {
    
    
        MyThread myThread = new MyThread();//创建线程MyThread的线程对象
        myThread.start();//开启线程
        for (int i = 0; i <= 5; i++){
    
    
            System.out.println("main()方法:" + i + "在运行");
        }
    }
}
//MyThread继承Thread类
class MyThread extends Thread{
    
    
    //重写父类的run()方法
    @Override
    public void run() {
    
    
        for(int i = 0; i <= 5; i++){
    
    
            System.out.println("MyThread的run()方法:" + i + "正在运行");
        }
    }
}

运行结果:
在这里插入图片描述从上面的结果可以看出来,两个方法的输出语句交替执行,这就实现了多线程。单线程和多线程的区别是,单线程是按照循序执行,而多线程可以同时运行,相互不影响。
    第二种:通过实现Runnable接口实现多线程
实例:

public class Example02 {
    
    
    public static void main(String[] args) {
    
    
        //创建RunnableDemo类的实例对象
        RunnableDemo runnableDemo = new RunnableDemo();
        //创建线程对象
        Thread thread = new Thread(runnableDemo);
        //开启线程,执行线程的run()方法
        thread.start();
        for (int i = 0;i <= 5; i++ ){
    
    
            System.out.println("mian方法在" + i + "在运行" );
        }
    }
}
//RunnableDemo类实现Runnable接口
class RunnableDemo implements Runnable{
    
    
    //当线程调用了start()方法时,该方法就会执行
    public void run() {
    
    
        for (int i = 0;i <= 5; i++ ){
    
    
            System.out.println("RunnableDemo类的run()方法:" + i + "在运行" );
        }
    }
}

运行结果:在这里插入图片描述
    Java继承中的单一性的局限性,才会有Runnable接口实现多线程。为了克服弊端,Thread类提供了另外一个构造方法Thread(Runnable r)。其中Runnable是一个接口,它只有一个方法run()方法。当通过Thread(Runnable r)构造方法创建线程对象时,我们只需要为该方法传递一个实现了Runnable接口的实例对象,这样创建的线程将会调用实现Runnable接口中的run()方法最为运行代码。而不需要调用Thread类中的run()方法。
    第三种:通过实现Callable接口实现多线程
实例:

public class Example03 {
    
    
    public static void main(String[] args)throws Exception{
    
    
        MyCallable callable = new MyCallable();//实例化MyCallable类的实例
        FutureTask<String> task = new FutureTask<String>(callable);
        new Thread(task).start();//启动线程
        String s = task.get();//获得返回值
        System.out.println(s);//输出结果
    }
}
//MyCallable实现Callable接口
class MyCallable implements Callable<String>{
    
    
    public String call() throws Exception {
    
    
        for (int i = 0;i <= 5; i++ ){
    
    
            System.out.println("MyCallable类的call()方法在" + i + "在运行" );
        }
        return "MyCallable执行完毕";
    }
}

    Thread类和Runnable接口的区别:
举一个例子比如一个车站有两个售票窗口,同时出售同一车次的车票。通过Thread类和Runnable接口两个例子看一下效果。
例1:

public class Example04 {
    
    
    public static void main(String[] args) {
    
    
        //创建一个线程对象
        BusTicket busTicket1 = new BusTicket();
        //为线程设置一个名称
        busTicket1.setName("窗口1");
        //开启该线程
        busTicket1.start();
        BusTicket busTicket2 = new BusTicket();
        busTicket2.setName("窗口2");
        busTicket2.start();
    }
}
class BusTicket extends Thread{
    
    
    private int ticket = 64;//车票数量
    @Override
    public void run() {
    
    
        int a = 0;
        while (a <= 64 ){
    
    
            a++;
            if (ticket > 0 ){
    
    
                //获取当前线程
                Thread thread = Thread.currentThread();
                //获取线程的名字
                String threadName = thread.getName();
                System.out.println(threadName + "正在发第" + ticket-- + "张票");
            }
        }
    }
}

运行结果:
在这里插入图片描述
    从上面的运行结果可以看出,因为车票是不可能一张同时出售两张,很明显这个结果是不正确的。也就是资源不共享。我们只能在程序中创建一个售票对象,开启多个线程同时去执行售票中的售票方法。也就是说多个线程运行同一个售票程序,这就会用到多线程中的Runnable接口。
例2:

public class Example05 {
    
    
    public static void main(String[] args) {
    
    
        //创建线程对象
        BusTicket2 busTicket = new BusTicket2();
        //启动线程并为线程设置名字
        new Thread(busTicket,"窗口1").start();
        new Thread(busTicket,"窗口2").start();
    }
}
class BusTicket2 implements Runnable{
    
    
    private int ticket = 64;//车票数量
    public void run() {
    
    
        int a = 0;
        while (a <= 64 ) {
    
    
            a++;
            if (ticket > 0 ){
    
    
                //获取当前线程
                Thread thread = Thread.currentThread();
                //获取线程的名字
                String threadName = thread.getName();
                System.out.println(threadName + "正在发第" + ticket-- + "张票");
            }
        }
    }
}

实例:
在这里插入图片描述
    创建一个线程对象,开启两个线程都调用售票方法,这样就确保了多个线程访问的是同一个资源。
加油吧!!!

猜你喜欢

转载自blog.csdn.net/qq_42494654/article/details/109370174