黑马程序员——高新技术---Java基础-多线程2

时间:2022-01-28 19:43:17

-----------android培训java培训、java学习型技术博客、期待与您交流!------------ 


JDK5Lock锁的使用: 

JDK5之后,提供一种的加锁的方式:Lock(接口)

java.util.concurrent.locks.Lock(接口)

Lock实现提供了比使用 synchronized方法和语句可获得的更广泛的锁定操作。

 

 参考帮助文档:

 使用方式:

 Lock l = new ReentrantLock();

    l.lock();//加锁

     try {

         //被同步的代码;

         

     } finally {

        l.unlock();//释放锁

     }


线程组:

我们可以将一些线程进行"分组",分组的目的是可以方便管理,统一进行一些操作;

 

 .默认线程组:

        所有线程,默认都属于一个线程组:main

.我们可以将一些线程放到我们指定一个"线程组"内;

                1).ThreadGroup:它表示一个线程组;

                2).实例化我们的线程对象;

                3).实例化一个Thread,使用:自定义线程组、线程、线程名称做参数;

 

 .我们可以对一个线程组内的所有线程进行统一操作,比如:停止一个线程组内的所有线程:

 

 

 

线程池:

 

  1.我们知道,对于同一个Thread对象,不能重复调用start()方法;

 2.如果我们再想使用,只能重新实例化一个新线程对象;如果这种实例化比较耗时,这样效率就很低;

 3.这种情况下,可以使用"线程池"

                 1).它可以缓存一些已经执行过的线程;

                 2).对于存在于缓存池中的线程,可以直接执行;

                3).JDK5之后,提供了"线程池"的概念:

Executors()

publicstatic ExecutorService newCachedThreadPool():创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。

publicstatic ExecutorService newFixedThreadPool(int nThreads):创建一个可重用固定线程数的线程池,

public static ExecutorService newSingleThreadExecutor():创建一个使用单个 worker 线程的 Executor,以*队列方式来运行该线程。新创建的单线程 Executor

返回值:ExecutorService()

Future<?>submit(Runnable task):执行并缓存线程对象;

停止线程:

shutdown();

 

 

JDK5的实现线程的方式:

  步骤:

1.实现Callable接口;

 2.重写:call()方法;

3.启动线程:

1.获取线程池:

        三种方式:

        Executors()

public static ExecutorService newCachedThreadPool():创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。

public static ExecutorServicenewFixedThreadPool(int nThreads):创建一个可重用固定线程数的线程池,

public static ExecutorServicenewSingleThreadExecutor():创建一个使用单个 worker 线程的Executor,以*队列方式来运行该线程。新创建的单线程 Executor

2.调用线程池的

ExecutorService()

Future<?> submit(Callable task):执行并缓存线程对象;

 

之前我们使用ThreadRunnable中的run()是不能接收返回值的,但JDK5的线程实现方式,可以接收返回值了。

 

 

 

匿名内部类的方式实现多线程程序

1.new Thread(){匿名的Thread的子类};

2.new Thread(匿名的Runnable的子类){};

3.new Thread(匿名的Runnable的子类){匿名的Thread的子类};  注意这个最后执行的还是匿名的Thread的子类中的方法。

具体代码:

public class Demo {
publicstatic void main(String[] args) {
//1.new Thread(){匿名的Thread的子类};
new Thread(){
//重写run()
@Override
public void run() {
System.out.println("a");
}
}.start();

//2.new Thread(匿名的Runnable的子类){};
new Thread(new Runnable(){
@Override
public void run() {
System.out.println("b");
}
}){}.start();

//3.new Thread(匿名的Runnable的子类){匿名的Thread的子类};
new Thread(new Runnable(){
@Override
public void run() {
System.out.println("c");
}
}){
@Override
public void run() {
System.out.println("d");//最终执行的是子类的run()
}
}.start();
}
}

定时器:

  1.在指定的时间,完成指定的任务;

 2.在指定的时间开始,每个多长时间,重复的执行指定的任务;

 

 Java中实现定时器:

 1.java.util.TimerTask(抽象类):描述具体任务:

                1).定义类,继承自:TimerTask;

                2).重写run()方法。将具体的任务,写到这里;

2.java.util.Timer类:启动TimerTask的:

                1).构造一个Timer对象;使用无参构造方法;

                2).public void schedule(TimerTask task, long delay):在指定的delay时间后,执行task中的任务;

                     public voidschedule(TimerTask task,long delay,long period)在指定的delay时间后,执行task中的任务;并且每隔period时间后,会反复的执行;

 

Wait(),sleep(),yield()方法的区别:                

1.wait():释放锁;Object类的;可以指定时间。使用notify()notifyAll()唤醒,或者"指定的时间"到了,会自动唤醒;

2.sleep():不释放锁;Thread类:必须指定时间。当休眠时间到,会自动唤醒;

3.yield():不释放锁;Thread类;是当前访问的线程退回到就绪状态。但是,当在"同步"方法中使用时,不会释放锁;

 

多线程的面试题:

1.多线程有几种实现方案,分别是哪几种?三种

                1).继承Thread类,重写run()方法

                        classMyThread extends Thread{

                                publicvoid run(){

                                }

                        }

                        main(){

                                MyThreadt = new MyTrhead();

                                t.start();

                        }

                2).实现Runnable接口,重写run()方法

                        classMyRunnable implements Runnable{

                                publicvoid run(){

                                 }

                        }

                        main(){

                                MyRunnablemyRun = new MyRunnable();

                                Threadt = new Thread(myRun);

                                t.start();

                         }

                3).实现Callable接口,重写:call()方法

                        classMyCallable implements Callable{

                                publicObject call() throws Exception{

                                        returnnull;

                                }

                        }

                        main(){

                                 //1.获取一个线程池

                                ExecutorServiceservice = Executors.newFixedThreadPool(2);

                                //2.执行submit()方法:

                                Futureresult =  service.submit(newMyCallable());

                                //获取返回值

                                 Objectvalue = result.get();

                                service.shutdown();

                        }

                 

  2.同步有几种方式,分别是什么?

                1).同步代码块:

                        synchronized(被锁的对象){

                                

                        }

                        被锁的对象:如果有一个线程访问此对象的某个同步代码块时,意味着这个线程当前锁住了整个对象,其它线程无法访问

                此对象内的所有同步的代码块及同步方法。

        A.在某个类中的同步代码块,通常锁的对象设定为:this;

    

                 2).同步方法:

                        publicsynchronized void show(){//锁的对象,默认为当前对象;

                        }

             静态的方法内可以包含"同步代码块",一般锁的对象是当前类的class对象。

  静态方法也可以是"同步的"

 

3.启动一个线程是run()还是start()?它们的区别?

                start()方法。

                区别:

                1.run():重写父类的方法,需要线程执行的内容,写到这里;

                2.start():启动线程,内部会自动调用run();

 

 4.sleep()wait()方法的区别:

                1.sleep():Thread类的方法;在同步方法内,不释放锁;必须指定时间,当时间到时,会自动醒来;

                2.wait():Object类的方法;在同步方法内,会释放锁;可以指定时间,也可以不指定时间。使用notify()notifyAll()唤醒,或者时间到了,自动醒来;

5.为什么wait(),notify(),notifyAll()等方法都定义在Object类中:

任何对象都可能会被多个线程并发访问,所以要求任何对象都有wait()notify()的功能,所以就定义在了Object类中。

 

设计模式的概念:

 

1.模式:人们在长期的生产经营活动中,会反复的遇到一些问题,并使用一些固定的方法去解决这些问题。这种反复的遇到问题并

  使用某种方式去解决问题的形式,就叫:模式;

2.Java与模式:以前的程序员在长期的使用Java语言开发过程中,会遇到各种问题,并使用某些手段去解决这些问题,这些手段通常是利用

            Java语言的一些特性:继承、封装、多态.....去解决问题;长期以来,就形成了一种固定的方式:就是使用Java语言解决

           某种问题的方案。

           

3.Java中设计模式的分类:

                创建型模式

                行为型模式

                结构型模式

 

简单工厂模式概述和使用

我们以前获取某些对象,都是直接实例化。

这种方式,将实例化对象与前端的代码混杂在一起。

 工厂模式:

1.对于某些对象的实例化,先建立某些"工厂类";

 2.前端获取对象,不用直接实例化,通过工厂类的某些方法来获取;

 3.特点:

         1).前端使用对象,不需要自己实例化,通过"工厂类"去获取;

         2).如果新增一个产品,需要修改"工厂类"

 

工厂方法模式的概述和使用

之前的 "简单工厂模式"如果新增一个产品的话,需要修改"工厂类"此模式,可以达到当新增产品时,无需修改任何类;

  步骤:

1.建立两个接口:

                1).产品接口:IAnimal

                2).工厂接口:IFactory

2.建立具体的产品类,和具体的工厂类;

                1).具体产品:Cat implements IAnimal

                2).具体工厂类:CatFactory implements Ifactory

 

 好处:如果新增产品时,无需对原来的任何类进行修改;

 弊端:类比较多;

 

单例模式之饿汉式

1.单例模式:

        单:一个;

        例:实例--对象;

2.在我们的程序运行期间,有些类的对象,只需要一个对象,这种情况下,就得需要将此类设计为:单例模式;

3.设计单例模式:例如:将Student设计为单例模式;

步骤:

1.任何类不能实例化Student类的对象:将Student的构造方法私有化;

2.Student内部持有一个自己对象的引用,(饿汉式--先实例化)

3.提供一个公有方法,为外部获取此引用; 

 

单例模式--懒汉式:

1.Student内的成员变量,先期不实例化;

2.在公有方法内,先判断是否为null,如果为null再实例化;

3.为了Student类的安全,公有方法可能会被多线程并发访问,为了安全,将此方法声明为同步的。

 

Runtime类:

java.lang.Runtime:

每个 Java应用程序都有"一个" Runtime类实例.使应用程序能够与其运行的环境相连接。可以通过 getRuntime方法获取当前Runtime对象。

内部:单例模式饿汉式实现;

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------