创建Java线程的方法

继承Thread类

构造一个内部类,继承thread类,然后重写run()方法。
如果需要用到共享数据,那么必须是静态属性;
举例:

class MyThread extends Thread{
    @Override
    /*
    重写run方法是为了让这个线程执行这个类的特殊任务;
     */
    public void run() {
        super.run();
        for (int i = 0; i < 100; i++) {
            try {
                sleep(1000);//等待1000秒后,在CPU分配到资源后,再执行线程
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(i % 2 == 0) System.out.println(getName()+i);//
            // Thread.currentThread().getName(),会给这个线程起一个默认的名字,不同线程名字不一样
            if(i % 20 == 0) yield();//这个方法是为了给其他线程让步,即到了20的倍数时,执行其他线程
            getPriority();//获得线程的优先级
            setPriority(MAX_PRIORITY);//设置线程的优先级,优先级高更高的概率执行,但不一定就是先执行。

        }
    }

    public MyThread(String name){
        super(name);
    }

    public MyThread(){

    }
}

public class ThreadTest {

    public static void main(String[] args)  {
        MyThread t1 = new MyThread();
        t1.setName("线程一");//要放在start()方法前

        t1.start();//只能用start()方法,如果用run()启动,就不是多线程了。start方法的两个功能:启动线程;启动run()方法。
        MyThread t2 = new MyThread();//只能新建一个对象来创建另一个线程,不然会报错
        t2.start();

        Thread.currentThread().setName("主线程");//这是给主线程命名
        for (int i = 0; i < 100; i++) {

            if(i % 2 != 0) System.out.println(Thread.currentThread().getName()+i);//
            // Thread.currentThread().getName(),会给这个线程起一个默认的名字,不同线程名字不一样
            if(i % 9 == 0) {
                try {
                    t1.join();//主线程进入阻塞状态,执行t1线程,直到t1执行完才会继续执行主线程
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(t1.isAlive());//判断线程生命周期是否结束

        }

    }

}

实现runnable接口

过程:
1.创建一个类实现runnable接口;
2.创建这个类的对象;
3.把这个对象作为参数,新建一个Thread类的对象;
4.用start方法启动

相比方式1的优点:
1.避免由于Java单继承特点导致的局限
2.更适合处理多个线程需要共同变量的情形。

与方式1的共同点:
1.thread类也是实现了runnable接口;
2.都需要重写run方法,把要执行的逻辑写进去。

举例:

public class RunnableTest implements Runnable{
    @Override
    public void run() {

    }

    public static void main(String[] args) {
        RunnableTest thread = new RunnableTest();
        Thread t1 = new Thread(thread);
        Thread t2 = new Thread(thread);
        t1.start();//因为Thread类的run方法规定,如果构造器传入runnable对象target且不为空,那么就调用target的run方法。

    }
}`

实现Callable接口

步骤:

  1. 创建Callable接口的实现类;
    2 .重写call()方法;
  2. 使用时创建实现类的对象;
  3. 将此对象作为参数传入FutureTask的构造器中并创建对象;
  4. 将FutureTask的对象作为参数传入Thread类的构造器;FutureTask是Runnable接口的实现类和Future接口的唯一实现类
  5. 如果想要获得call()方法的返回值,可以使用FutureTask的get()方法。

call() 相比run()的优点:
1.有返回结果;
2.call()可以抛异常,被外面的方法捕获异常信息;
3.call()支持泛型;

举例:

class Sum implements Callable{


    @Override
    public Object call() throws Exception {
        int sums = 0;
        for (int i=0; i<=50; i++){
            if(sums % 10 ==0) System.out.println("和:"+sums);
            sums+=i;
        }
        return sums;
    }
}

public class CallableTest {

    public static void main(String[] args) {
        Sum s = new Sum();

        FutureTask ft = new FutureTask(s);

        new Thread(ft).start();

        try {
            Object sum = ft.get();
            System.out.println(sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

线程池

线程池把几个线程放在一起,使用的时候从线程池里取出线程,不用的时候还回去,而不像其他方式那样直接销毁对象。

接口:
ExceutorService:真正的线程池接口,excute()用于runnable接口的实现类,submit()用于Callable接口的实现类。常见实现类是ThreadPoolExecutor,如果要设置线程的属性如数量、生命周期,必须转化成实现类,可以采用强转的方式。

举例:thread\ThreadPoll.java

线程池的优点

相比其他三种方式的优点:

  1. 线程池中的线程可以重复使用,不用每次创建新的对象,节约了资源。
  2. 减少了创建新线程需要的时间,提高了响应速度。
  3. 方便管理线程,可以设置诸如线程数量、生命周期的属性。

线程池的种类

  • newFixedThreadPool:返回一个固定线程数量的线程池。当一个新的任务提交时,如果由空闲线程就会立即执行
  • newSingleThreadExecutor:返回只有一个线程的线程池,多余的任务会加入到任务队列,先入先出。
  • newCachedThreadPool:返回的线程数量不固定,优先使用已创建的线程。如果任务的数量超过了线程的数量,就新建一个线
  • newScheduledThreadPool:返回一个ScheduledExceutorService对象,线程数量可以指定

举例:

public class ThreadPoll {

    public static void main(String[] args) {
        ExecutorService service = Executors.newFixedThreadPool(10);
        Executors.newCachedThreadPool();
        ThreadPoolExecutor s1 = (ThreadPoolExecutor) service;
        s1.setCorePoolSize(15);

        service.execute(new Runthread());
        service.submit(new CallThread());
        service.shutdown();

    }
}

class Runthread implements Runnable{
    @Override
    public void run() {

    }
}

class CallThread implements Callable{
    @Override
    public Object call() throws Exception {
        return null;
    }
}

自定义线程池

ThreadFactory:一个接口,专门用来创建新线程。

ThreadPoolExecutor类

  • 功能:
    新建线程池,在需要自定义线程池的时候,就用这个类来实现。
  • 构造器
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory)

举例:

    public void customThread(){
        ExecutorService service = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS,
                new SynchronousQueue<Runnable>(), new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                return null;
            }
        })
        {
            //拓展线程池的方法
            //在线程之前执行
            @Override
            protected void beforeExecute(Thread t, Runnable r) {
                super.beforeExecute(t, r);
            }

            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                super.afterExecute(r, t);
            }

            //在销毁过程中执行
            @Override
            protected void terminated() {
                super.terminated();
            }
        };
        //submit和execute都是执行线程,参数是要执行的方法
        service.submit(this::task);
        //
        service.execute(this::task);
        service.shutdown();
    }

    void task(){

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值