首页 > 编程语言 > 详细

Java多线程之多线程的创建

时间:2019-11-21 15:52:12      阅读:66      评论:0      收藏:0      [点我收藏+]

创建多线程有四种的方式

1、继承Thread类

步骤:

  1、创建一个继承Thread的子类

  2、在子类中重写run()方法。此线程执行的操作声明在run()方法中。

  3、创建子类的对象

  4、调用Start()方法。start()的作用是启动线程并执行run().  

代码实现如下:

 

//打印10以内的偶数
class MyThread extends Thread{
    @Override
    public void run() {
        for (int i=0;i<10;i++){
            if (i%2==0) {
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
}
//打印10以内的奇数
class MyThread1 extends Thread{
    @Override
    public void run() {
        for (int i=0;i<10;i++){
            if (i%2!=0) {
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
}

public class ThreadTest {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
//       调用start():①启动当前线程②调用当前线程的run()方法
        myThread.start();
MyThread1 myThread1
= new MyThread1(); myThread1.start(); for (int i=0;i<10;i++){ if (i%2==0) { System.out.println(Thread.currentThread().getName()+":"+i); } } System.out.println("hellow"); } }

 

输出结果如下:

main:0
main:2
main:4
main:6
main:8
hellow
Thread-0:0
Thread-0:2
Thread-0:4
Thread-0:6
Thread-0:8
Thread-1:1
Thread-1:3
Thread-1:5

 

2、实现Runnable接口

步骤如下:

  1、创建实现Runnable接口的实现类

  2、实现类中重写run()方法。

  3、创建实现类的对象

  4、将实现类的对象作为参数传递到Thread构造器中,创建一个Thrad类的对象

  5、通过Thread对象调用start()方法

代码实现如下:

class MyThread2 implements Runnable{

    @Override
    public void run() {
        for (int i =0;i<10;i++) {
            if (i%2==0){
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
}



class MyThread3 implements Runnable{

    @Override
    public void run() {
        for (int i =0;i<10;i++) {
            if (i%2!=0){
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
}

 

public class ThreadTest1 {
    public static void main(String[] args) {
        MyThread2 myThread2 = new MyThread2();
        Thread thread2 = new Thread(myThread2);
        //setName():为线程赋名
        thread2.setName("线程一");
        thread2.start();

        MyThread3 myThread3 = new MyThread3();
        Thread thread3 = new Thread(myThread3);
        thread3.setName("线程二");
        thread3.start();

        Thread.currentThread().setName("主线程");

        for (int i =0;i<10;i++) {
            if (i%2==0){
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }

    }
}

运行结果如下:

主线程:0
主线程:2
主线程:4
主线程:6
主线程:8
线程一:0
线程一:2
线程一:4
线程一:6
线程一:8
线程二:1
线程二:3
线程二:5
线程二:7
线程二:9

 使用实现Runnable接口对比继承Thread类:

  1. 实现接口的方式没有类的单继承性的局限性
  2. 两者都需要重写run()方法,将执行的操作声明其中。
  3. 实现的方式更适合来处理多个线程有共享数据的情况
  4. Thread implements Runnable(实现Thread类最终还是继承Runanle接口

源码如下:

public
class Thread implements Runnable {
    /* Make sure registerNatives is the first thing <clinit> does. */
    private static native void registerNatives();
    static {
        registerNatives();
    }

 

 

3、实现Callable接口

步骤如下:

1、创建一个实现Callable接口的实现类

2、实现类重写call()方法。此线程执行的操作声明在该方法中。

3、创建实现类的对象

4、将实现类的对象作为参数传递到FutureTask的构造器中,创建FutureTask对象

5、将FutureTask对象作为参数传递到Thread构造器中,创建Thread对象

6、通过Thread对象调用start()方法

7、也可以通过get()方法得到call()方法的返回值

代码实现如下:

//创建实现类
    class NumberThread implements Callable {

    @Override
    public Object call() throws Exception {
        int sum = 0;
        //线程需要进行的操作

        for (int i = 0; i <= 10; i++) {
            if (i%2==0){
                System.out.println(Thread.currentThread().getName()+":"+i);
                sum+=i;
            }
        }

        return sum;
    }
}
public class ThreadTest3 {
    public static void main(String[] args) {

        //创建实现类的对象
        NumberThread numberThread = new NumberThread();

        //将实现类的对象作为参数传递到FutureTask构造器中
        FutureTask futureTask = new FutureTask(numberThread);

        //传递到Thread中
        Thread thread = new Thread(futureTask);

        thread.setName("callable线程");

        thread.start();

        //获取返回值
        try {
            Object sum = futureTask.get();
            System.out.println("总和为"+sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        Thread.currentThread().setName("主线程");
        for (int i = 0; i <10 ; i++) {

            if(i%2!=0){

                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
}

 

运行结果如下:

callable线程:0
callable线程:2
callable线程:4
callable线程:6
callable线程:8
callable线程:10
总和为30
主线程:1
主线程:3
主线程:5
主线程:7
主线程:9

实现Callable接口的方式与实现Runnable接口的比较:

  1. 有返回值
  2. 支持泛型(以后再说)
  3. 可以抛出异常。被外部操作捕捉,得到异常的信息。

 

4、线程池

1、实现接口或者继承类的器中一种

2、指定线程的数量

3、执行指定线程的操作

4、关闭线程

代码如下:

 

class NumberThread1 implements Runnable{

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

class NumberThread2 implements Runnable{

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

 

 

 

 

public class ThreadTest4 {
    public static void main(String[] args) {
        //①指定线程数量
        ExecutorService service = Executors.newFixedThreadPool(10);
        //②执行
        service.execute(new NumberThread1());//适用于runnable接口
        //service.submit(Callable callable);  适用于Callable接口
        service.execute(new NumberThread2());
        //③关闭
        service.shutdown();
    }
}

使用线程池的好处:

1、提高响应的速度(减少创建现成的时间)
2、降低资源消耗(重复利用线程池中的线程,不需要每次都创建)
3、便于线程管理
  1. corePoolSize:核心池的大小
  2. maximumPoolSize:最大线程数
  3. KeepAlliveTime:线程没有任务时做多保持多长时间后停止

 

 

 5、关于线程还有一些方法的使用

 

class HelloThread extends Thread{

    @Override
    public void run() {
        for (int i = 0; i <100 ; i++) {

            //sleep():线程睡眠,在时间1000ms期间是阻塞的
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(i%2==0){
                System.out.println(getName()+":"+getPriority()+":"+i);
            }
            //yield():释放当前线程的cpu
            if(i%20==0){
              yield();
            }
        }
    }
}
public class ThreadMethodTest {
    public static void main(String[] args) {

        HelloThread h1 = new HelloThread();
        //setName():给分线程赋予名称
        h1.setName("线程1");
        //setPriority():给分线程赋予优先级
        //MAX_PRIORITY:10  最高级
        //MIN _PRIORITY:1  最低级
        //NORM_PRIORITY:5  -->默认优先级
        //注意:高优先级的线程要抢占低优先级线程cpu的执行权。但是只是从概率上讲,高优先级的线程高概率的情况下
        //被执行。并不意味着只有当高优先级的线程执行完以后,低优先级的线程才执行。
        h1.setPriority(Thread.MIN_PRIORITY);
        h1.start();

        //给主线程赋予名称
        Thread.currentThread().setName("主线程");
        //给主线程赋予优先级
        Thread.currentThread().setPriority(Thread.MAX_PRIORITY );
        for (int i = 0; i < 100; i++) {
            if (i%2==0){
                //主线程的当前名字
                System.out.println(Thread.currentThread().getName()+":"+Thread.currentThread().getPriority()+":"+i);
            }

            //join():线程阻塞  当前线程在i=20时,线程阻塞  等待下一个线程完成 在重新运行
            if (i==20){
                try {
                    h1.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

 

 

 

 

 

 

Java多线程之多线程的创建

原文:https://www.cnblogs.com/Y-xiaojian/p/11905762.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!