java 多线程(一)

介绍

并行:一起行走,在一段时间内发生。
并发:同时发生,在某一刻时间完成。

进程:
一个进程也即一个任务
window和linux都是多任务操作系统
进程与进程之间是相互独立的

线程:
一个进程可以有多个线程,至少有一个线程
一个线程代表时间上的线性顺序执行
线程是CPU划分资源的最小单位(时间片和内存)
一个进程下的线程可以资源共享

单核:cpu是通过划分时间片来实现多线程,实际上是并行
多核:cpu可以并发实现多线程
对于程序员来说,Java平台和操作系统屏蔽了单核与多核问题。

多线程编程,一般来说解决两个问题:速度和设计可管理性。方法是并发(或者在单核cpu上通过并行模拟)实现,所以也称为并发编程,引发的问题称为并发问题。
(1)更快的执行
将一个程序分为多个片段,分别执行。
多核:web服务器常见,实际上现在一般的电脑都是多核了。并发执行,理所当然的更快了。
单核:一般来说,这种情况下任务整体的顺序执行应该要快于分片的并行执行,因为需要考虑到上下文切换的消耗。但如果任务中包含阻塞情况,通常是I/O,而导致程序停止下来等待外部条件的变化,那么多线程就会提高速度。
事实上,从性能角度来看,没有任务会阻塞,那么在单处理器上使用多线程就没有任何意义。(但目前多核更常见)
(2)设计可管理性
GUI和WEB环境(比如Servlet)

创建

1、继承Thread类

public class demo01 {
    public static void main(String[] args) {
        Dog dog = new Dog("小白");
        Dog dog2 = new Dog("小黑");
        dog.start();
        dog2.start();
    }
}
class Dog extends Thread{
    int count = 0;
    String name;
    public Dog(){}
    public Dog(String name){this.name = name;}
    @Override
    public void run(){
        while(++count<101) {
            System.out.println(name+"跑了:" +count + "米");
        }
    }
}

2、实现Runnable接口

public class demo02 {
    public static void main(String[] args) {
        Cat cat1 = new Cat("小红");
        Cat cat2 = new Cat("小绿");
        Thread t1 = new Thread(cat1);
        Thread t2 = new Thread(cat2);
        t1.start();
        t2.start();
    }
}
class Cat implements Runnable{
    int count = 0;
    String name;
    public Cat(){}
    public Cat(String name){this.name = name;}
    @Override
    public void run(){
        while(++count<101) {
            System.out.println(name+"跑了:" +count + "米");
        }
    }
}

3、执行器Executor

public class Test03 {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(new Cat("小红"));
        executorService.execute(new Cat("小绿"));
        executorService.shutdown();
    }
}

4、通过Callable和FutureTask

public class Test04 {
    public static void main(String[] args) {
        A a = new A();
        FutureTask<Integer> ft = new FutureTask<>(a);
        for(int i = 0;i < 100;i++)
        {
            System.out.println(Thread.currentThread().getName()+" 的循环变量i的值"+i);
            if(i==20)
            {
                new Thread(ft,"有返回值的线程").start();
            }
        }
        try
        {
            System.out.println("子线程的返回值:"+ft.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
class A implements Callable<Integer>{

    @Override
    public Integer call() throws Exception {
        int i = 0;
        for(;i<100;i++)
        {
            System.out.println(Thread.currentThread().getName()+" "+i);
        }
        return i;
    }
}

posted @ 2020-10-16 16:22  黑白猫123  阅读(79)  评论(0编辑  收藏  举报