Java多线程

Process与 Thread

程序◆说起进程,就不得不说下程序。程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念
进程◆而进程则是执行程序的一次执行过程,它是一个动态的概念。是系统资源分配的单

线程◆通常在一个进程中可以包含若干个线程,当然一个进程中至少有一个线程,不然没
有存在的意义。线程是CPU调度和执行的的单位。


注意:很多多线程是模拟出来的,真正的多线程是指有多个cpu,即多核,如服务
器。如果是模拟出来的多线程,即在一个cpu的情况下,在同一个时间点,cpu只能
执行一个代码,因为切换的很快,所以就有同时执行的错局

三种创建线程的方式

1、Thread class  --->  继承 Thread 类

public class ThreadTestOne extends Thread{
    @Override
    public void run(){
          //重写run方法
          for(int i = 0; i < 20 ; i ++){
                System.out.println("重写run方法" + i);
          }
    }

     public static void main(String[] args){
           //创建一个线程对象
           ThreadTestOne threadTestOne = new ThreadTestOne();

           //调用 start() 方法开启线程,此时两跳线程交替运行,主线程中间会交叉执行run方法
           threadTestOne.start();
       //调用 run() 方法,此时先运行重写的run方法,不推荐
       //threadTest.run(); 不能调用此方法

       for(int i = 0;i<200;i++){
          System.out.println("我在学习多线程" + i);
       }
} }

 练习

package com.alipay.sofa.web.test.base;

import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;

public class TestThread02 extends Thread {
    private String url;
    private String name;

    public TestThread02(String name, String url) {
        this.url = url;
        this.name = name;
    }

    //线程执行体
    @Override
    public void run(){
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.downloader(name,url);
        System.out.println("下载了图片,命名为:"+name);
    }

    public static void main(String[] args) {
        TestThread02 t1 = new TestThread02("picture1","https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1792667613,1083374801&fm=26&gp=0.jpg");
        TestThread02 t2 = new TestThread02("picture2","https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1792667613,1083374801&fm=26&gp=0.jpg");
        TestThread02 t3 = new TestThread02("picture3","https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1792667613,1083374801&fm=26&gp=0.jpg");

        t1.start();
        t2.start();
        t3.start();
    }

class WebDownloader{
        public void downloader(String name,String url){
            try {
                FileUtils.copyURLToFile(new URL(url),new File(name));
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("IO异常,download方法出现问题");
            }
        }
}
}

2、Runnable 接口   --->  实现 Runnable 接口

 

package com.alipay.sofa.web.test.base;

public class TestThread03 implements Runnable {

    //必须重写run方法
    @Override
    public void run() {
        for (int i=1;i<100;i++) {
            System.out.println("运行run方法");
        }
    }

    public static void main(String[] args) {
        TestThread03 testThread03 = new TestThread03();
        //Thread thread = new Thread(testThread03);
        //thread.start();
        //创建线程对象,通过线程对象来开启线程,这是个静态代理
        new Thread(testThread03).start();

        for (int i = 1; i<100 ;i++){
            System.out.println("主函数的进程");
        }
    }
}

例子:

package com.alipay.sofa.web.test.base;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;

public class TestThreadRunnable implements Runnable {
    //创建成员变量和带参的构造方法去接收url和name
    private String url;
    private String name;

    public TestThreadRunnable(String url, String name) {
        this.url = url;
        this.name = name;
    }

    //写线程,线程要做的事情
    @Override
    public void run() {
        WebDownloadr wl = new WebDownloadr();
        wl.webDownloder(url,name);
        System.out.println("线程下载了图片,命名为:"+name);
    }

    public static void main(String[] args) {
        //创建多对象
        TestThreadRunnable tRunnable01 = new TestThreadRunnable("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1792667613,1083374801&fm=26&gp=0.jpg","RunnablePicture");
        TestThreadRunnable tRunnable02 = new TestThreadRunnable("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1792667613,1083374801&fm=26&gp=0.jpg","RunnablePicture");
        TestThreadRunnable tRunnable03 = new TestThreadRunnable("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1792667613,1083374801&fm=26&gp=0.jpg","RunnablePicture");

        //创建多线程静态代理
        new Thread(tRunnable01).start();
        new Thread(tRunnable02).start();
        new Thread(tRunnable03).start();
    }

//内部类,去实现下载图片转换成文件
class WebDownloadr{
        public void webDownloder(String url,String name){
            try {
                FileUtils.copyURLToFile(new URL(url),new File(name));
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("IO异常,download方法出现问题");
            }
        }
}
}

 例子2:并发线程

package com.alipay.sofa.web.test.base;

public class MultiThreadConcurrency implements Runnable {
    private int ticket = 20;
    @Override
    public void run() {
        //写具体线程要做的逻辑
        while (true){
            if (ticket <= 0){
                break;
            }
            //设置一个延时,模拟人抢票的时间
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(Thread.currentThread().getName()+"拿到了第"+ticket--+"张票");
        }
    }

    public static void main(String[] args) {
        MultiThreadConcurrency za = new MultiThreadConcurrency();

        new Thread(za,"安安").start();
        new Thread(za,"周平").start();
        new Thread(za,"xuzhongyin").start();
    }
}

3、Callable 接口  --->  实现 Callable 接口

 好处:

1、可以定义返回值

2、可以抛出异常

例子如下:

package com.alipay.sofa.web.test.base;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;

public class TestThreadCallable implements Callable {
    private String name;
    private String url;

    //有参的构造函数,用来传递url 和 name
    public TestThreadCallable(String url, String name) {
        this.name = name;
        this.url = url;
    }

    //线程的执行体
    @Override
    public Boolean call() throws Exception {
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.downloader(url,name);
        System.out.println("");
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        TestThreadCallable trace1 = new TestThreadCallable("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1792667613,1083374801&fm=26&gp=0.jpg","t1");
        TestThreadCallable trace2 = new TestThreadCallable("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1792667613,1083374801&fm=26&gp=0.jpg","t1");
        TestThreadCallable trace3 = new TestThreadCallable("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1792667613,1083374801&fm=26&gp=0.jpg","t1");

        //创建执行服务
        ExecutorService ser = Executors.newFixedThreadPool(3);

        //提交执行
        Future<Boolean> t1 = ser.submit(trace1);
        Future<Boolean> t2 = ser.submit(trace2);
        Future<Boolean> t3 = ser.submit(trace3);

        //获得线程的返回值
        Boolean response1 = t1.get();
        System.out.println(response1);
        Boolean response2 = t2.get();
        System.out.println(response2);
        Boolean response3 = t3.get();
        System.out.println(response3);

        //关闭服务
        ser.shutdownNow();
    }

class WebDownloader{
        public void downloader(String url,String name){
            try {
                FileUtils.copyURLToFile(new URL(url), new File(name));
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("IO异常");
            }
        }
}
}
原文地址:https://www.cnblogs.com/xuzhongyin/p/13498465.html