Java——多线程的简单实现

中高阶架构师的必经之路:

高可用、高并发、高性能网站开发

 

 

多线程基本概念:

多个进程同时进

线程:调度和执行的单位(cpu的调度)

进程:作为资源分配的单位(操作系统的分配)

线程是进程的一部分

 

 

用户线程和守护线程

用户线程:java虚拟机所有用户线程dead后,程序就会结束

守护线程:辅助用户线程进行工作,不适用于I/O输入输出以及计算操作,避免程序结束后,任务不能执行完。

守护线程使用情景:

1、JVM垃圾回收

2、内存管理

3、数据库连接池监听状态等

 

 

多线程的实现

1、基础Thread类,实现run方法

实例1:

 

//多实现少继承:
//继承也许需要继承多个类而实现不需要考虑这些
public class test10 {
    //创建线程:1、继承Thread+重写run
    //2
、创建子类对象+start

   
public static void main(String[] args){


    }
}

class MyThread extends Thread{
    public void run(){
        for(int i = 0;i<20;i++){
            System.out.println("听歌");
       
}

    }

    public static void main(String[] args){
        //启动线程
       
MyThread my = new MyThread();
       
my.start();//两条线程同时运行,不会互相干扰
       
for(int i = 0;i<20;i++){
            System.out.println("跳舞");//cpu去调配
       
}


    }
}

 

运行结果

 

 

继承Thread类,实现run方法,通过实例的start()方法,告知系统可以开始运行该run方法,根据系统调度器分配运行时间片,进行运行。

多次运行,运行结果不相同。

实现跳舞的线程和实现听歌的线程不相同。

 

 

 

实例2(多线程与I/O结合:多线程实现图片下载)

public class test11 {
   
public static void main(String[] args){
        String url1 =
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1540353806265&di=e4258c87892a1b4080891f0d03241a74&imgtype=0&src=http%3A%2F%2Fimg2.dwstatic.com%2Fnews%2F1809%2F401517849603%2F401517880783.jpeg";
        String url2 = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1540948740&di=6ec8f3d51fdc501444cd58d47971db87&imgtype=jpg&er=1&src=http%3A%2F%2F07.imgmini.eastday.com%2Fmobile%2F20171102%2F20171102173205_2fb5db37f5a7fcb32d6054adcb21f28a_1.jpeg";
        String url3 = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1540354085940&di=2aec582b87582ecb0426bede2462f987&imgtype=0&src=http%3A%2F%2Fpic.anzogame.com%2Flol%2Fnews%2F20140829%2F14092426723701_org.jpg";
       
MyThread2 dl1 = new MyThread2(url1,"E:/for_file/2.png" );
       
MyThread2 dl2 = new MyThread2(url2,"E:/for_file/3.png" );
       
MyThread2 dl3 = new MyThread2(url3,"E:/for_file/4.png" );
       
dl1.start();
       
dl2.start();
       
dl3.start();
   
}

}


class Downloadimg{


   
public void Download(String url, String path){
       
try {
            FileUtils.copyURLToFile(
new URL(url),new File(path) );
       
} catch (IOException e) {
            e.printStackTrace()
;
       
}

    }
}


class MyThread2 extends Thread{
   
private  String url;
    private
String path;

    public
MyThread2(String url,String path){
       
this.url = url;
        this
.path = path;
   
}
   
public void run() {
        Downloadimg dli =
new Downloadimg();
       
dli.Download(this.url,this.path );
   
}
}

 

引用Commons IO jar包中的方法进行文件内容的复制,其实变相于下载。

 

实现runnable接口

class MyThread implements Runnable{
    public void run(){
        for(int i = 0;i<5;i++){
            System.out.println("听歌");
       
}

    }

    public static void main(String[] args){
        //创建实现类对象
        MyThread my = new MyThread();
       
//创建代理类对象
        Thread t = new Thread(my);
       
t.start();
        for
(int i = 0;i<5;i++){
            System.out.println("跳舞");//cpu去调配
        }


    }
}

 

实现接口,重写run方法,然后创建子类对象和Thread类的代理对象,通过将子类对象以传参的形式传给代理对象,通过调用代理对象的start()方式进行调度。

 

如果只运行一次,可以如上进行编码;

 

相比较继承类,推荐实现接口的方法:

1、方便共享资源

2、继承类单继承的局限性

 

Thread类的源码:

参数1:可运行目标

参数2:姓名(给线程赋予称号)

 

实例:

public class test10 {
    public static void main(String[] args){
        MyThread my = new MyThread();
        new
Thread(my,"小二").start();
        new
Thread(my,"小一").start();
   
}


}

class MyThread implements Runnable{
    private int num = 20;
   
@Override
   
public void run() {
        while(true){
            if(num<0){
                break;
           
}
            System.out.println(Thread.currentThread().getName()+"----"+num--);
       
}
    }

}

单任务多线程并给每个线程设定名字

 

运行结果

当一个任务有多个代理共同执行时,如果有网络延迟等问题,会导致并发,这时候就是线程不安全,需要进行处理。

 

实现Callable的Call方法

public class test10 {
    public static void main(String[] args) {
        //创建执行服务
        MyThread my1 = new MyThread();
       
MyThread my2 = new MyThread();
       
ExecutorService es = Executors.newFixedThreadPool(2);
       
//提交执行
        Future<String> r1 = es.submit(my1);
       
Future<String> r2 = es.submit(my2);
       
//获取结果
        try {
            String re1 = r1.get();
           
System.out.println(re1);
           
String re2 = r2.get();
           
System.out.println(re2);
       
} catch (InterruptedException e) {
            e.printStackTrace();
       
} catch (ExecutionException e) {
            e.printStackTrace();
       
}
        //关闭服务
        es.shutdownNow();

   
}
}

class MyThread implements Callable<String> {

    @Override
   
public String call() throws Exception {
        return "有些失望是不可避免的,但大部分的失望,都因为你高估了自己。";
   
}
}

 

运行结果

 

比较复杂,暂时只需要了解:

继承Callable接口,实现call方法,确定返回值类型。

执行操作:

1、创建执行服务 ExecutorService es = Executors.newFixedThreadPool(2);

2、提交任务  Future<String> r1 = es.submit(my1);

3、接受返回值 String r = r1.get();

4、结束服务 es.shutdownNow();

 

java与I/O流详解

CommonsIO环境搭建​​​​​​​

java多线程快速实现​​​​​​​

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/xxtnt/article/details/83345301