Java多线程和注解

前言

介绍Java实现多线程的机制,以及Java的反射机制。同时还包括Java的注解。


目录

前言

一、Java线程概述

二、Java创建线程的方式

1、Java创建线程的三种方式

2、对线程的一些操作 

三、线程调度

1、Java线程调度的机制和常用方法

2、多线程并发

3、守护线程和定时器

四、Java反射机制

1、反射机制主要的四大类:

2、获取类的三种方式: 

3、反射机制获取字段

4、反射机制获取方法 

6、反射机制获取构造方法和继承的基类及接口

五、Java注解

1、Java注解简介

2、注解的属性

3、反射注解


一、Java线程概述

        启动JVM时就是创建了一个进程,而一个进程又可以创建多个线程。运行Java程序时JVM至少有两个线程,一个是主线程去执行main( )方法,另一个进行垃圾回收。

        Java中,进程之间的内存不共享,线程之间栈区的内存不共享,堆区和方法区的内存共享。  


二、Java创建线程的方式

1、Java创建线程的三种方式

        (1)、编写类继承java.lang.Thread,并重写run( )方法,然后创建对象,调用对象的start( )方法

//创建线程的第一种方式:
//创建一个类继承Thread,重写run()方法,然后创建该对象,调用对象的start()方法启动线程
//注意Thread是java.lang包下的,所以不需要导包

class ThreadTest1 extends Thread{
    @Override
    public void run() {
        System.out.println("新的线程创建了");
    }
}


public class Test01 {
    public static void main(String[] args) {
        //创建线程对象,调用线程的start()方法
        ThreadTest1 t = new ThreadTest1();
        t.start();
        System.out.println("这是主线程");
    }
}

运行一次的输出结果是:

        这是主线程
        新的线程创建了 

因为是不同的线程,所以这两句话的输出的先后顺序不一定。不过由于线程的创建和调用方法需要时间,因此这个例子中main( )方法中的输出会先进行。可以在输出之前加个循环,循环几十万次,然后再输出。

 调用start( )方法启动线程时,会创建一个新的栈空间。不过start( )方法仍然是在当前栈也就是主栈完成的,start( )方法完成,创建好栈空间后,会自动将run( )方法压栈,调用该方法。

      

        (2)、实现java.lang.Runnable接口,也是重写run( )方法,然后创建对象,传入Thread的有参构造方法中,再调用创建的Thread对象的start( )方法

//创建对象的第二种方式:
//实现Runnable接口,重写run()方法。然后创建对象传入Thread的有参构造中,调用Thread对象的start()方法

class ThreadTest2 implements Runnable{

    @Override
    public void run() {
        System.out.println("利用第二种方式创建线程");
    }
}
public class Test02 {
    public static void main(String[] args) {
        ThreadTest2 rt = new ThreadTest2();
        Thread t = new Thread(rt);
        //也是调用start()方法创建新的栈然后调用run()方法
        t.start();
        System.out.println("主线程");
    }

}

        (3)、实现Callable接口,重写call()方法。创建对象传入FutureTask的有参构造中,然后将FutureTask再传入Thread的有参构造,调用start()方法

//创建线程的第三种方式:
//实现Callable接口,重写call()方法。创建对象传入FutureTask的有参构造中,然后将FutureTask再传入Thread的有参构造,调用start()方法
//该接口在java.util包下
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

class ThreadTest3 implements Callable {

    @Override
    public Object call() throws Exception {
        System.out.println("要重写call()方法");
        return "返回值";
    }
}
public class Test03 {
    public static void main(String[] args) {
        ThreadTest3 ct = new ThreadTest3();
        //需要传入到未来任务类FutureTask的有参构造中
        FutureTask ft = new FutureTask(ct);
        //然后将FutureTask再传入Thread的有参构造,调用start()方法
        Thread t = new Thread(ft);
        t.start();
        Object o = null;
        //这种方式创建的线程可以拿到返回值
        //注意,是用传入Thread中的未来任务类FutureTask的get()方法拿到的Callable中call()方法的返回值
        try {
            o = ft.get();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
        System.out.println(o);//返回值
    }
}

 注意,该类创建线程的方式要导入java.util包。

这种方式创建线程的特点在于可以得到线程的返回值,使用未来任务类FutureTask的get( )方法可以的到Callable中call( )方法的返回值。但是这个方法会造成当前线程阻塞。

2、对线程的一些操作 

        (1)、设置和获取线程的名字

                使用setName( )和getName( )方法修改和得到线程的名字

        (2)、获取当前线程对象

                使用Thread.currentThread( )方法返回一个线程对象

        (3)、让线程睡眠的方法

                用Thread.sleep( )方法让当前线程睡眠 ,用实例方法interraput( )方法终止睡眠。注意,终止睡眠只能是终止别的线程,不能终止当前线程。

        (4)、终止线程的方法

                在线程类中添加一个布尔类型的标记属性


class ThreadTest4 extends Thread{
    //为线程终止设置一个标记
     private boolean run = true;
    @Override
    public void run() {
        for(int i = 1;i<100;i++){
            if(run){
                //让当前线程睡眠的方法
                try {
                    Thread.sleep(100);//传入的是毫秒数,该方法有异常
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("支线程第"+i+"次执行");
            }
            else{
                return;
            }
        }

    }

    public boolean isRun() {
        return run;
    }

    public void setRun(boolean run) {
        this.run = run;
    }
}
public class  Test04{
    public static void main(String[] args) {
        ThreadTest4 t1 = new ThreadTest4();
        t1.start();
        //设置和得到线程名字
        System.out.println(t1.getName());//Thread-0
        t1.setName("线程2");
        System.out.println(t1.getName());//线程2

        //获取当前线程
        Thread t2 = Thread.currentThread();
        System.out.println(t2.getName());//main

        //让当前线程睡眠的方法
        try {
            Thread.sleep(5000);//传入的是毫秒数,该方法有异常
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //终止线程睡眠,注意不能终止当前线程的睡眠
        t1.interrupt();

        //用标记终止线程
        t1.setRun(false);//只执行到45次就停止了

    }

}


三、线程调度

1、Java线程调度的机制和常用方法

         Java的线程调度采用的是抢占式的方式,各线程具有优先级可用线程对象的getPriority( )方法和setPriority( )方法来获取和设置线程执行的优先级。数字越大,代表优先级越高。最高优先级为10,最低为1,默认优先级为5。

静态方法Thread.yield( )方法会暂停当前对象,将当前对象状态由执行转换为就绪,而不是阻塞。并开始其它就绪线程。 

实例方法join( )会将调用该方法的线程对象合并到当前线程,会使原来的线程阻塞。

public class Test05 {
    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i = 1;i<100;i++){
                    System.out.println("支线程第"+i+"次执行");
                }
            }
        });
        t.start();
        //默认优先级是5
        System.out.println(t.getPriority());//5

        //将t线程合并到当前线程,该方法有异常
        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        for(int i = 1;i<10;i++){
       
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值