【java多线程1】进程,线程,线程实现方式的概述

一.进程与线程

进程:是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位

线程:是进程中的一个执行路径,是cpu分配的基本单位。一个进程最少拥有一个线程。

二. Java多线程的创建及启动

1.继承Thread类

优点获取当前线程简单直接使用this即可,缺点java不支持多继承,继承了Thread就无法继承其他类了。

public class MyThread extends Thread {
    
    private int i = 0;

    @Override
    public void run() {
        for (i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
}



public class ThreadTest {

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
            if (i == 30) {
                // 创建一个新的线程  myThread1  此线程进入新建状态
                Thread myThread1 = new MyThread();
                // 创建一个新的线程 myThread2 此线程进入新建状态
                Thread myThread2 = new MyThread();  
                // 调用start()方法使得线程进入就绪状态   
                myThread1.start();
                // 调用start()方法使得线程进入就绪状态                     
                myThread2.start();                     
            }
        }
    }
}

2.实现Runnable接口

 优点接口可以多实现,减少耦合

public class MyRunnable implements Runnable {
    private int i = 0;

    @Override
    public void run() {
        for (i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
}



public class ThreadTest {

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
            if (i == 30) {
                // 创建一个Runnable实现类的对象
                Runnable myRunnable = new MyRunnable(); 
                // 将myRunnable作为Thread target创建新的线程
                Thread thread1 = new Thread(myRunnable); 
                Thread thread2 = new Thread(myRunnable);
                // 调用start()方法使得线程进入就绪状态
                thread1.start(); 
                thread2.start();
            }
        }
    }
}

说明: 继承Thread类与实现Runnable接口创建线程方式相似,不同的地方在于,因为Thread类本身也是实现了Runnable接口。

/**Thread类中对Runnable接口中run()方法的实现*/
@Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

也就是说,当执行到Thread类中的run()方法时,会首先判断target是否存在,存在则执行target中的run()方法,也就是实现了Runnable接口并重写了run()方法的类中的run()方法  

3.使用Callable接口和FutureTask类创建线程

优点是具有返回值 

public class MyCallable implements Callable<Integer> {
    private int i = 0;

    // 与run()方法不同的是,call()方法具有返回值
    @Override
    public Integer call() {
        int sum = 0;
        for (; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
            sum += i;
        }
        return sum;
    }

}



public class ThreadTest {

    public static void main(String[] args) {
        // 创建MyCallable对象
        Callable<Integer> myCallable = new MyCallable();    
        // 使用FutureTask来包装MyCallable对象
        FutureTask<Integer> ft = new FutureTask<Integer>(myCallable); 

        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
            if (i == 30) {
                // FutureTask对象作为Thread对象的target创建新的线程
                Thread thread = new Thread(ft);
                // 线程进入到就绪状态   
                thread.start();                      
            }
        }

        System.out.println("主线程for循环执行完毕..");
        
        try {
            // 取得新创建的新线程中的call()方法返回的结果
            int sum = ft.get();            
            System.out.println("sum = " + sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }
}

需要特别注意的是:不能对同一线程对象两次调用start()方法。原因是threadStatus的在一次调用后值就变化了,再次进入的时候通过判断threadStatus的值从而产生异常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章