第八章:线程与进程(复习,强化笔记)

线程与进程的具体解释,区别等不说了,不会那不用参加秋招了。
一、多线程的实现方法
1、主线程中的等待发
缺点:线程多的化就会让代码显得冗余。
2、添加join进行等待
不够细粒度。

public class CycleWait implements Runnable{
    private String value;
    @Override
    public void run() {
        try {
            Thread.currentThread().sleep(5000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        value="we are ready";

    }
    public static void main(String[] args) throws InterruptedException {
        CycleWait cycleWait=new CycleWait();
        Thread thread=new Thread(cycleWait);
        thread.start();//一定要让线程开始执行
//        while (cycleWait.value==null){
//            try {
//                Thread.currentThread().sleep(100);
//            }catch (InterruptedException e){
//                e.printStackTrace();
//            }
//        }//方法1
//        thread.join();//方法2
        System.out.println(cycleWait.value);

    }

3、通过FuntureTsak和线程池
创建一个MyCallablelei用于重写Call函数

public class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        String value="test";
        System.out.println("Ready to work");
        Thread.currentThread().sleep(5000);
        System.out.println("tesk done");
        return value;
    }
}

①、FuntureTask方法

public class FutureTaskDame {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<String > task=new FutureTask<String>(new MyCallable());
        new Thread(task).start();
        if (!task.isDone()){
            System.out.println("task has not finished,please wait!");
        }
        System.out.println("task return"+task.get());
    }
}

特别关注一下isDone()函数跟get函数,isDone()用于处理call函数是否执行完了没有,get分为两个,一个是无参,用于阻塞调用它的线程一直到call函数执行完了没有。有参的里面有时间参数用于处理时间超时的情况。
②、创建线程池

public class ThreadPoolDame {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService newCachedThreadPool= Executors.newCachedThreadPool();
        Future<String> future=newCachedThreadPool.submit(new MyCallable());
        if (!future.isDone()){
            System.out.println("task has not finished,please wait!");
        }
        System.out.println(future.get());
        newCachedThreadPool.shutdown();//线城池一定要关闭
    }
}

仔细深究源代码就会发现FuturTask继承RunnableFuture接口而RunnableFuture接口有继承Future接口和Runnable。
二、run函数传参的方法
1、构造函数传参
2、成员变量或方法传参
定义变量或者时set方法赋值
3、回调函数传参
写代码块等
三、Thread中start和run的方法
1、start创建了一个线程并启动,同时调用了run函数
2、run只是Thread类中的一个方法
四、Thread和Runnable的区别
1、Thread是类,Runnable是接口
2、Thread类继承了Runnable接口
五、线程的六种状态
1、新建
2、运行
3、堵塞
4、结束
5、有时间的等待
①、sleep()方法
②、wait(),join()加时间
③、LockSupport.park
Nanos()方法和LockSupport.park
Until()
6、没有时间的等待
①、wait(),join()加时间
②、LockSupport.park()
六、sleep和wait的区别
①、sleep可以运用在任何地方
②、wait只能运用在synchronized方法或者synchroized快中
③、sleep是Thread中的方法,wait是Object方法
原因:
sleep结束只释放CPU,不会导致锁行为改变
wait不仅让出CPU还会释放已占有的同步资源锁
举个栗子

public class WaitSleepDemo {
    public static void main(String[] args) {
        final Object lock =new Object();
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("thread A is waiting to get lock");
                synchronized (lock){
                    try {
                        System.out.println("thread A get lock");
                        Thread.sleep(20);
                        System.out.println("thread A do wait method");
                        lock.wait(1000);
                        System.out.println("thread A is done");
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        try {
            Thread.sleep(10);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("thread B is waiting to get lock");
                synchronized (lock){
                    try {
                        System.out.println("thread B get lock");
                        System.out.println("thread is sleeping 10ms");
                        Thread.sleep(10);

                        System.out.println("thread B is done");
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                }
            }
        }).start();

    }
}

运行结果
thread A is waiting to get lock
thread A get lock
thread B is waiting to get lock
thread A do wait method
thread B get lock
thread is sleeping 10ms
thread B is done
thread A is done
从例子中可以看出,线程A先执行,当线程A要睡20秒时,线程B就会开始执行,但进入synchroized要获取锁,此时的锁在线程A这里所以B不能执行,当A运行完wait后就会放出锁,此时B也开始执行了。
我们先运行sleep在运行wait看看

public class WaitSleepDemo {
    public static void main(String[] args) {
        final Object lock =new Object();
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("thread A is waiting to get lock");
                synchronized (lock){
                    try {
                        System.out.println("thread A get lock");
                        Thread.sleep(20);
                        System.out.println("thread A do wait method");
                       Thread.sleep(1000);
                        System.out.println("thread A is done");
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        try {
            Thread.sleep(10);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("thread B is waiting to get lock");
                synchronized (lock){
                    try {
                        System.out.println("thread B get lock");
                        System.out.println("thread is sleeping 10ms");
                        lock.wait(10);

                        System.out.println("thread B is done");
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                }
            }
        }).start();

    }
}

结果
thread A is waiting to get lock
thread A get lock
thread B is waiting to get lock
thread A do wait method
thread A is done
thread B get lock
thread is sleeping 10ms
thread B is done
可以看出thread A do wait method和
thread A is done是连这显示的,所以sleep不会让出锁,只有线程执行结束了才可以。
七、yield函数的作用
给线程调度机一个暗示,不会让出当前线程已占用的锁。
八、中断函数interrupt的运用(多理解看代码)
①、堵塞函数会抛出异常,但要看具体情况
interr详细讲解
②、正在运行的函数则只是将中断标志位至ture,继续运行不受影响。
阻塞状态代码

public class InterruptDemo {
    public static void main(String[] args) throws InterruptedException {
        Runnable interruptTask=new Runnable() {
            @Override
            public void run() {
                int i=0;
                try {
                    while (!Thread.interrupted()){
                        Thread.sleep(100);
                        i++;
                        System.out.println(Thread.currentThread().getName()+"("+Thread.currentThread().getState()+")"+i);
                    }
                }catch (InterruptedException e)
                {
                    System.out.println(Thread.currentThread().getName()+"("+Thread.currentThread().getState()+") catch InterruptedException");
                }
            }
        };
        Thread t1=new Thread(interruptTask,"t1");
        System.out.println(t1.getName()+"("+t1.getState()+") is new");
        t1.start();
        System.out.println(t1.getName()+"("+t1.getState()+") is started");
        Thread.sleep(300);
        t1.interrupt();
        System.out.println(t1.getName()+"("+t1.getState()+") is interrupted");
        Thread.sleep(300);
        System.out.println(t1.getName()+"("+t1.getState()+") is interrupted now");


    }}

运行状态

public class InterruotDemo2 extends Thread{
    public void run(){
        while(true){
            if(Thread.currentThread().isInterrupted()){
                System.out.println("Someone interrupted me.");
            }
            else{
                System.out.println("Thread is Going...");
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {

        InterruotDemo2 t1=new InterruotDemo2();
        t1.start();
        Thread.sleep(3000);
        t1.interrupt();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值