java多线程相关的知识点

java多线程有实现Runnable接口,继承Thread类,或者实现Callable接口。其中Callable接口有还回值。
多线程具有安全问题,在共享数据的时候,数据变量的值会被修改。如果不是共享没有问题,通过加锁,或者采用synchronized 同步方法或者同步代码块,可以实现多线程的安全问题。

实现Runnable接口的需要重写call方法,其是多线程执行的地方。

class  RandomNumberTest implements Callable {

    private  int N=136;
    private List<Integer> list=new LinkedList<Integer>();
    private ReadWriteLock r=new ReentrantReadWriteLock();

    @Override
    public Object call() throws Exception {
//      r.writeLock().lock();

//      synchronized (this){
        while (N>0){

         Thread.sleep(3);
         System.out.println(this+" "+Thread.currentThread()+"     "+N);
         list.add(N);
         N--;

        }

//      }
//      r.writeLock().unlock();
        return list;
    }
}

Runnable需要Future接口,或者FutureTask辅助,才能实现多线程。
通过Future的get方法取回多线程的返回值。

public static  void test() {

         RandomNumberTest rnt=new RandomNumberTest();
         FutureTask ftk1=new FutureTask(rnt);
         FutureTask ftk2=new FutureTask(rnt);
         new Thread(ftk1).start();
         new Thread(ftk2).start();
         try {
             LinkedList<Integer> lnk1= (LinkedList) ftk1.get();

             for(int elem:lnk1){
                System.out.print(elem+" ");
             }

         } catch (InterruptedException e) {
             e.printStackTrace();
         } catch (ExecutionException e) {
             e.printStackTrace();
         }

    }


通过线程池,实现多线程的创建。 JVAV默认提供了4个线程池。BlockingDeque是阻塞队列,存放线程池里面的task。 ThreadPoolExecutor通过execute执行多线程。如果是Callable接口有返回结果的通过submit执行。

    public static  void tetsExpool() throws ExecutionException, InterruptedException {

        RandomNumberTest rnt=new RandomNumberTest();
        BlockingDeque<Runnable> bq=new LinkedBlockingDeque<Runnable>(3);
        ThreadPoolExecutor t=new ThreadPoolExecutor(3,6,1000L,TimeUnit.SECONDS,bq);

        Future ftk1=t.submit(rnt);
        Future ftk2=t.submit(rnt);

        LinkedList<Integer> lnk1= (LinkedList) ftk1.get();

        System.out.println("----------------"+lnk1.size());
        for(int elem:lnk1){
            System.out.print(elem+" ");
        }

    }

多线程安全问题很诡异,加锁可能形成死shuo

死锁一般不容易形成,形成了也不好修改,需要打破死锁形成的条件。

死锁类。

class DeadLockDemo implements Runnable {

    private int num;
    private  boolean flag;

    public DeadLockDemo(int num,boolean flag){
        this.num=num;
        this.flag=flag;
    }

    public void run() {
        System.out.println(Thread.currentThread().getName());
        while (num > 0) {

        if(flag)
        {


            synchronized (ApplicationListener.b1) {
                System.out.println(this + " true  " + Thread.currentThread() + "     " + num);
                num--;
                try {
                    Thread.sleep(3999);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                synchronized (ApplicationListener.b2) {
                    System.out.println(this + " " + Thread.currentThread() + "     " + num);
                    num++;
                    try {
                        Thread.sleep(60 * 100); // 为测试,占用了就不放
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        else{
            synchronized (ApplicationListener.b2) {
                num++;
                System.out.println(this + "   false " + Thread.currentThread() + "     " + num);

                try {
                    Thread.sleep(3199);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                synchronized (ApplicationListener.b1) {
                    num--;
                    System.out.println(this + " " + Thread.currentThread() + "     " + num);

                    try {
                        Thread.sleep(60 * 100); // 为测试,占用了就不放
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

        }


        }

    }


}


通过调用会形成死锁。


    public static void  deadLock(){

        DeadLockDemo d1=new DeadLockDemo(33,true);
        DeadLockDemo d2=new DeadLockDemo(66,false);
        Thread t1=new Thread(d1);
        Thread t2=new Thread(d2);
        t1.start();
        t2.start();

    }

情况如下所示。


4976516-d5b4d4931d76bfae.png
image.png

转载于:https://www.jianshu.com/p/afdd20cc64e7

猜你喜欢

转载自blog.csdn.net/weixin_34221112/article/details/91074322