多线程(二)线程的基本用法

在这里插入图片描述
1.线程的生命周期
创建线程–>调用start()就绪–>等待CPU时间片调度后运行–>死亡

2.创建线程的方法
到底有多少种呢?
a)1.继承Thread,覆盖父类的run方法
b)2.实现Runable接口,实现run方法
c)3.实现Callable接口,实现call()方法,Callable传入FutureTask对象的构造函数;
因为FutureTask是实现RunnableFuture接口,RunnableFuture 接口继承Runnable, Future两个接口,所以FutureTask可以当作Runable传入new Thread();
泛型V是返回类型,所以方法3是有返回值的线程调用
(其实callable还是属于方法2)

public class NewThread {
//方法一
    public static class UserThread extends Thread{
        @Override
        public void run() {
            System.out.println("This is UserThread -- " + Thread.currentThread().getName());
        }
    }
//方法二
    public static class UserRunnable implements Runnable{

        @Override
        public void run() {
            System.out.println("This is UserRunnable -- " + Thread.currentThread().getName());
        }
    }

    public static void main(String[] args) {

        UserThread userThread = new UserThread();
        userThread.start();

        UserRunnable userRunnable = new UserRunnable();
        new Thread(userRunnable).start();


    }
}
//方法3
public class UseFuture {
	
	
	/*实现Callable接口,允许有返回值*/
	private static class UseCallable implements Callable<Integer>{
		private int sum;
		@Override
		public Integer call() {
			System.out.println("Callable子线程开始计算!");
			for(int i=0 ;i<5000;i++){
//	        	if(Thread.currentThread().isInterrupted()) {
//					System.out.println("Callable子线程计算任务中断!");
//					return null;
//				}
				/*try {
					Thread.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}*/
				sum=sum+i;
				System.out.println("sum="+sum);
	        }  
	        System.out.println("Callable子线程计算结束!结果为: "+sum);  
	        return sum; 
		}
	}
	
	public static void main(String[] args)  {

		UseCallable useCallable = new UseCallable();
		//包装
		FutureTask<Integer> futureTask = new FutureTask<>(useCallable);
		new Thread(futureTask).start();

		Random r = new Random();
		int r1 = r.nextInt(100);
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("**********r1 value = "+r1);
		if(r1>50){
			try {
				System.out.println("Get UseCallable result = "+futureTask.get());
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
		}else{
			System.out.println("Cancel................. ");
			futureTask.cancel(true);
		}

	}

}

3.run()方法跟start()方法的区别,我们都知道,创建一个线程之后,线程要启动就是执行start()方法,所以,start()方法就是启动线程的方法,通过调用本地方法(native)的start0方法,启动线程,而run()方法其实就是一个普通的方法,供给线程跑业务用的;

4.join()方法的使用
可以理解成CPU资源抢夺,运行中的线程A里面,B线程调用了join()方法,则A让出时间资源,进入阻塞状态,等待B线程执行完成之后,A重新进入就绪状态进入抢占CPU时间资源列表

5.yield()方法的使用
运行中线程A调用yield()方法之后,则让出时间片,进入就绪状态重新等待CPU调度,不会释放锁资源

6.sleep()方法的使用
线程进入睡眠,等待唤醒或者设置的时间到了,线程进入睡眠不释放锁资源

7.wait()

8.notify()/notifyAll()

9.interrupte的使用
a)interrupt()方法:
用处:中断当前线程,调用之后,会使得当前线程收到一个中断请求状态,但是不会直接中断,需自行处理(协作式)
例子:
以下代码执行了interrupt()方法之后,还是会继续run()方法里面的业务代码

public class EndThread {
    public static class UserThread extends Thread{
        @Override
        public void run() {
            String threadName = Thread.currentThread().getName();
            Long startTime = System.currentTimeMillis();
            while (true){
            //while (!Thread.interrupted()){
                System.out.println("Thread is running ...and use time : " + (System.currentTimeMillis()-startTime));
            }
            //System.out.println(threadName + " interrupt : " + Thread.interrupted());
        }
    }

    public static void main(String[] args) {
        UserThread userThread = new UserThread();
        userThread.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        userThread.interrupt();
    }
}

可以把while里面的true改为!Thread.interrupted(),判断当前线程是否被中断
b)interrupted()
这是一个静态方法,用来判断当前线程是否被中断,返回boolean,调用之后,当前线程状态重置为非中断状态
c)isInterrupted()
用来判断使用的线程是否被中断,返回boolean
d)interrupted 与isInterrupted 的区别
interrupted 是一个静态的,调用之后,当前线程会被变成非中断状态,源码注释这样写的: if the current thread has been interrupted;意思是这个只能用在当前线程
isInterrupted 非静态的,调用之后线程状态不变,也可以带入参数改变线程状态,源码注释这样写的: if this thread has been interrupted;
e)死锁是不会理会中断标志的

10.线程的结束
a)Thread的stop()方法,但是一般不会建议使用这个,因为这个方法会直接将线程强制停止,导致业务执行到一半,线程占用的资源不会正常释放,容易出现问题;
一个很重要的概念,线程应该是协作式的,而不是强制式;
b)线程里面的业务代码执行完毕,正常结束
c)收到interrupt中断请求后。代码结束当前业务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值