【Java基础知识】多线程常用数据模式有什么?

2020-10-15 17:23发布

8条回答
不吃鱼的猫
2楼 · 2020-10-15 17:49

什么是多线程:多线程就是多个路径,多个任务,没有多个任务,就没有必要开启多线程;
进程:在操作系统中运行中的程序,我们称作进程。

每个进程又可以开辟多条路,做不同的事情,不如既可以听音乐,也可以看图像,也可以看字幕,等;

进程是操作系统CPU调度到了,是一个动态的概念,一个进程匹配一个程序,线程是一个程序开辟多条路径;

很多是一个CPU运行的多线程,其实是CPU分配不同的时间段给线程,系统来回的在线程之间切换速度很快,造成错觉;

真正的多线程是多核CPU;


无需指教
3楼 · 2020-10-16 08:27

程序(软件):数据和指令的集合。软件架构:B/S  C/S  软件分类:系统软件,应用软件。

进程:正在运行的程序,会在内存中分配空间。

线程:进程中的多条路径。

多线程是指有多条线程并发的执行。

并发:多条线程在同一时间段内交替执行。

并行:多条线程同时执行。

创建线程:

1.继承:extends Thread类  继承的子类需要重写run方法

2.实现:implements Runnable接口

注意:无论是继承还是实现,直接调用重写过的run方法是无法开启多线程的,jvm中默认start()方法开启多线程,start()方法会默认调用重写的run()方法。

3.线程创建方式的优缺点:

① 继承方式写法简单。实现方式写法相对比较复杂
② 继承与实现都是通过 start 方法才能开启线程。
③ 继承的扩展性和灵活性都低于实现方式的扩展性和灵活性
④ 继承的方式,耦合度高于实现的方式。
实际开发中,使用实现形式要多于继承形式。

 

使用继承来开启多线程  :代码示例:

复制代码

 1 package com.Allen.Thread; 2  3 public class Demo5 { 4     public static void main(String[] args) { 5         ExtendsThread et=new ExtendsThread(); 6         et.start(); 7         for(int j=0;j<100 for (int i = 65; i >

复制代码

执行结果:

 

 可以看到两个线程在交替运行。

 

使用实现Runnable接口来开启多线程:代码示例:

复制代码

 1 package com.Allen.Thread; 2  3 public class Demo6 { 4  5     public static void main(String[] args) { 6         ImplementsRunnable ir=new ImplementsRunnable(); 7         Thread td=new Thread(ir); 8         td.start(); 9         for (int j = 0; j < 1000; j++) {10             System.out.println("====j"+j);11         }12     }13 }14 class ImplementsRunnable implements Runnable{15 16     @Override17     public void run() {18         for (int i = 0; i < 1000; i++) {19             20             System.out.println("***********i"+i);21         }22     }23 }

复制代码

 

执行结果:

 

实现Runnable接口来开启多线程还可以使用匿名对象  代码示例:

复制代码

 1 package com.Allen.Thread; 2  3 public class Demo6 { 4  5     public static void main(String[] args) { 6          7         Thread td=new Thread(new ImplementsRunnable());   //这里使用的是匿名对象 8         td.start(); 9         for (int j = 0; j < 1000; j++) {10             System.out.println("====j"+j);11         }12     }13 }14 class ImplementsRunnable implements Runnable{15 16     @Override17     public void run() {18         for (int i = 0; i < 1000; i++) {19             20             System.out.println("***********i"+i);21         }22     }23 }

复制代码

 

 

线程的执行原理:

线程的执行:CPU的抢占式的调度模式,抢占CPU的时间片

 

不同的线程不共享栈空间,需要开辟栈空间单独运行

 

线程的生命周期:

***1. 线程的生命周期 / 线程的状态
① 生命周期:从事物的出生,到消亡的过程。
***② 线程生命周期的状态:
1 》初始状态 : 创建了线程对象,但是没有调用 start 方法开启线程。
2 》可运行状态: 调用了 start 方法,到线程队列中排队,抢占 cpu 的时间片。但是还没有抢占上

3 》运行状态: 抢到了 cpu 的时间片。正在执行。
4 》 终止状态: cpu 时间片之内完成了线程的执行。
5 》 阻塞状态: cpu 时间片执行期间,遇到了意外的情况。
③ 线程的生命周期,指同一个线程在不同时期的状态。
④ java 中,线程的生命周期通过类来表示不同的状态 : Thread.State
new
至今尚未启动的线程处于这种状态。
runnable
正在 Java 虚拟机中执行的线程处于这种状态。
blocked
受阻塞并等待某个监视器锁的线程处于这种状态。
waiting
无限期地等待另一个线程来执行某一特定操作的线程处于这种状态。
timed_waiting
等待另一个线程来执行取决于指定等待时间的操作的线程处于这种状态。
terminated
已退出的线程处于这种状态。

 

线程的常用方法;

1.getName()返回线程的名称

2.currentThread()获取当前线程的引用对象。

线程的名称  main方法所在的线程为主线程 ,线程名为main

      自定义的线程:Thread-0,Thread-1    默认格式:Thread-index  其中index从0开始  线程的名称可以设置

3.setName () 设置线程的名称

4.***getpriority()/setPriority()  返回线程的优先级/设置线程的优先级

***线程的优先级:从1到10,默认为5,最高优先级为10,最低优先级为1

线程如果优先级越高,抢占CPU时间片的可能性越大,默认一个线程创建时,优先级为5.

5.isDaemon()/setDeamon(true)  判断该线程是否为守护线程/设置线程为守护线程,参数值为true。

守护线程是用来守护用户线程,为用户线程进行准备或者守护的工作。

随着用户线程的消亡,守护线程无论是否执行完都会随着用户线程消亡。

6.join()等待该线程的终止,相当于用户调用。

7****sleep(ms) 休眠,毫秒值

8.start()开启线程的方法,会默认调用run()方法,进行线程的开启。

9.yield()退出当前正在执行的线程,让给其他线程执行,线程的让步。

 

守护线程的代码示例:

复制代码

 1 package com.Allen.Thread; 2  3 public class Demo7 { 4  5     public static void main(String[] args) { 6         DaemonThread dh=new DaemonThread(); 7         dh.setDaemon(true); 8         dh.start(); 9         for (int j = 0; j <20 j);11         }12     }13 14 }15 class daemonthread extends thread{16     @override17     public void run() {18         for (int i = 0; i >

复制代码

 

执行结果:

 

本例daemonthread线程要打印倒99,但是随着主线程的消亡,守护线程也消亡了,但是为什么主线程 到19就消亡了,而守护线程却到了28呢?这是因为有延迟,不能立即结束。

主线程和守护线程的关系就像人与影子的关系,共存亡。

 

 线程的安全问题:

1.多线程:多个线程并发执行。

2.多线程在执行时,会引发安全问题

3. 通过银行账户取款的模拟来演示多线程的安全问题。
4. 多线程的安全问题:
多个线程共同访问共享资源 ( 共有的资源 ) 时,由于线程的调度机制是抢占式调度,可能会发生多个线程在执行时,
同时操作共享资源,导致程序执行结果与预期不一致的现象。

 

5. 解决多线程的安全问题:
1> 解决方式一:同步:但是该方式会导致效率低,相当于单个线程执行。
a) 同步方式: ( 加锁 )
① 同步方法 : 相当于同步代码块中的 this 锁。
格式 :
权限修饰符 修饰符 synchronized 方法的返回值 方法的名称 ( 参数 )
② 同步代码块:
1 》 同步锁对象 :任意对象
格式 : synchronized ( 任意对象 ){
加锁的代码
}
2 》同步 this 锁:
③ 同步代码块和同步方法加锁时,需要注意:
《 1 》 加锁必须是给共享资源加的。
《 2 》 必须加的是同一把锁。

 多线程安全问题的代码示例:

 

复制代码

 1 package com; 2 /** 3          1.多线程 : 多个线程并发执行。 4          2.多线程在执行时,会引发安全问题。 5          3.通过银行账户取款的模拟来演示多线程的安全问题。 6          4.多线程的安全问题: 7              多个线程共同访问共享资源(共有的资源)时,由于线程的调度机制是抢占式调度,可能会发生多个线程在执行时, 8              同时操作共享资源,导致程序执行结果与预期不一致的现象。 9          5.解决多线程的安全问题:10               1>解决方式一:同步:但是该方式会导致效率低,相当于单个线程执行。11                  a)同步方式:(加锁)12                      ① 同步方法: 相当于同步代码块中的this锁。13                          格式 :14                           权限修饰符  修饰符   synchronized 方法的返回值 方法的名称(参数)15                      ② 同步代码块:16                          1》 同步锁对象 :任意对象17                              格式 :synchronized (任意对象){18                                  加锁的代码19                              }20                          2》同步this锁: 
21                      ③ 同步代码块和同步方法加锁时,需要注意:22                         《1》 加锁必须是给共享资源加的。23                         《2》 必须加的是同一把锁。24  */25 public class 多线程的安全问题 {26     public static void main(String[] args) {27         Account a=new Account();28         //多线程29         Thread  t=new Thread(a);30         Thread  t1=new Thread(a);31         t.setName("张三");32         t1.setName("李四");33         t.start();34         t1.start();35     }36 }37 class  Account implements Runnable{38     double balance=1000;//账户余额39     Object obj=new Object();//任意对象40     String s=new String();41     //同步方法 42     @Override43     public /*synchronized*/ void run() {44         //同步锁对象,任意对象。45         synchronized (this) {//this锁46             //取款47             if (balance > 0) {48                 //休眠49                 try {50                     Thread.sleep(1000);51                 } catch (InterruptedException e) {52                     // TODO Auto-generated catch block53                     e.printStackTrace();54                 }55                 balance -= 1000;56                 System.out.println(Thread.currentThread().getName() + "取款后,金额为" + balance);57             } else {58                 System.out.println(Thread.currentThread().getName() + "余额不足");59             }60         }61     }62 }

复制代码

 ======================================================================

 

复制代码

 1 package com; 2 /** 3  4          1.多线程的安全问题:  ① 多个线程 ② 共享资源。 5          2.同步: 判断多个线程是否加的是同一把锁。 6             ① 同步方法 7             ② 同步代码块: 8                1》 锁对象(任意对象) 9                2》this锁10                3》静态锁 (静态对象)11                4》类锁(.class)12  */13 public class 继承方式下的多线程的安全问题 {14     public static void main(String[] args) {15         AccountThread  a=new AccountThread();16         AccountThread  a1=new AccountThread();17         a.setName("张三");18         a1.setName("李四");19         a.start();20         a1.start();21         22     }23 }24 class  AccountThread extends Thread{25  static double balance=1000;//账户余额26  //静态锁27  static Object o=new Object();28     //同步方法 29     @Override30     public  void run() {31         //类锁32             synchronized (AccountThread.class) {//this 
33                 //取款34                 if (balance > 0) {35                     //休眠36                     try {37                         Thread.sleep(1000);38                     } catch (InterruptedException e) {39                         // TODO Auto-generated catch block40                         e.printStackTrace();41                     }42                     balance -= 1000;43                     System.out.println(Thread.currentThread().getName() + "取款后,金额为" + balance);44                 } else {45                     System.out.println(Thread.currentThread().getName() + "余额不足");46                 }47             }48     }49 }

复制代码

 

PS:alt+方向键可以上下平移代码
ctrl+加减号可以调节eclipse的字体大小

shift+ctrl+delete  删除整行

复制代码

 1 package com.Allen.Thread; 2 public class Demo8 { 3     public static void main(String[] args) {        
 4         CountMoney td1=new CountMoney(); 5         CountMoney td2=new CountMoney();        
 6         td1.setName("张先生"); 7         td2.setName("李先生"); 8         td1.start(); 9         td2.start();    
10     }11 }12 class CountMoney extends Thread{13     static double count=1000;14     static Object o=new Object();15     public void run() {16         synchronized(o) {17         if(count>0) {18             try {19                 Thread.sleep(1000);20             } catch (InterruptedException e) {21                 // TODO Auto-generated catch block22                 e.printStackTrace();23             }24             count-=1000;25             System.out.println(Thread.currentThread().getName()+"取款成功,余额:"+count);26         }else {27             System.out.println(Thread.currentThread().getName()+"余额不足");28         }29     }30     }31     32 }


有点好奇
4楼 · 2020-10-16 09:00
  就多线程来说,我们开始设想只有两个线程(>2时是不是算数学归纳法?)那么如果两个独立的线程会发生什么呢? 
  1。当一个线程进入moniter(也就是说站用一个object),另一个线程只有等待或返回,而我们把返回就称为一种模式,这种模式的英文是Balking。
  2。这两个线程可以是有序的执行,而不是让OS来调度,这时我们要用一个object来调度,这种模式称为Scheduler。(这个词及其含义其实OS中就有)。 
   3。如果这两个线程同时读一个资源,我们可以让他们执行,但如果同时写的话,你闭着眼睛都会知道可能出现问题,这时我们就要用另一种模式(Read/Write Lock)。
   4。如果一个线程是为另一个线程服务的话,比如IE中负责数据传输的线程和界面显示的线程,当一个图片没有传完时,另一个线程就无法显示,至少是部分没有传完。那么这时我们要用一个模式称为生产者和消费者,英文是Producer-Consumer。 
   5。两个线程的消亡也可以不是完全又OS来控制的,这时我们需要给出一个条件,使得每个线程在符合条件是才消亡,也就是有序的消亡,我们称为Two-Phase Termination。 
   那么有这5个线程模型,基本上可以用到大多数编程任务中。我需要指出的三点是: 
   1。从高层次上我们可以再验证是否含盖了所有的情况。 
   2。其实模式不是完全固定的或者说象定律一样,而模式可以为不同的情况进行适当 的调整和组合,目的是为了简洁和高效。 
   3。学习模式是为了具备更好的分析问题的能力。 而似乎这些来自西方的技术,并且是目前的,我们有没有呢?其实我个人有个大胆的推测,我认为我们祖先的《孙子兵法》就是很好设计模式,因为它符合设计模式需要的基本特征,就是在特定的条件下,用某种特定的方式合理且高效的解决问题。


梦到内河_
5楼 · 2020-10-16 09:41

多线程就是多个路径,多个任务可以同时进行

魏魏姐
6楼 · 2020-10-16 09:48

1、吞吐量:你做WEB,容器帮你做了多线程,但是他只能帮你做请求层面的。简单的说,可能就是一个请求一个线程。或多个请求一个线程。如果是单线程,那同时只能处理一个用户的请求。

2、伸缩性:也就是说,你可以通过增加CPU核数来提升性能。如果是单线程,那程序执行到死也就利用了单核,肯定没办法通过增加CPU核数来提升性能。鉴于你是做WEB的,第1点可能你几乎不涉及。那这里我就讲第二点吧。


我是大脸猫
7楼 · 2020-10-19 09:53

java多线程的几种实现方式:

1.继承Thread类,重写run方法
2.实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的target
3.通过Callable和FutureTask创建线程
4.通过线程池创建线程  (上一篇已经讲过了)

前面两种可以归结为一类:无返回值,原因很简单,通过重写run方法,run方式的返回值是void,所以没有办法返回结果 
后面两种可以归结成一类:有返回值,通过Callable接口,就要实现call方法,这个方法的返回值是Object,所以返回的结果可以放在Object对象中

方式1:继承Thread类的线程实现方式如下:

public class ThreadDemo01 extends Thread{    public ThreadDemo01(){        //编写子类的构造方法,可缺省    }    public void run(){        //编写自己的线程代码        System.out.println(Thread.currentThread().getName());    }    public static void main(String[] args){         ThreadDemo01 threadDemo01 = new ThreadDemo01();         threadDemo01.setName("我是自定义的线程1");        threadDemo01.start();               System.out.println(Thread.currentThread().toString());      }}


程序结果: 
Thread[main,5,main] 
我是自定义的线程1

线程实现方式2:通过实现Runnable接口,实现run方法,接口的实现类的实例作为Thread的target作为参数传入带参的Thread构造函数,通过调用start()方法启动线程

public class ThreadDemo02 {    public static void main(String[] args){         System.out.println(Thread.currentThread().getName());        Thread t1 = new Thread(new MyThread());        t1.start();     }}class MyThread implements Runnable{    @Override    public void run() {        // TODO Auto-generated method stub        System.out.println(Thread.currentThread().getName()+"-->我是通过实现接口的线程实现方式!");    }   }


程序运行结果: 
main 
Thread-0–>我是通过实现接口的线程实现方式!

线程实现方式3:通过Callable和FutureTask创建线程 
a:创建Callable接口的实现类 ,并实现Call方法 
b:创建Callable实现类的实现,使用FutureTask类包装Callable对象,该FutureTask对象封装了Callable对象的Call方法的返回值 
c:使用FutureTask对象作为Thread对象的target创建并启动线程 
d:调用FutureTask对象的get()来获取子线程执行结束的返回值

public class ThreadDemo03 {    /**     * @param args     */    public static void main(String[] args) {        // TODO Auto-generated method stub        Callable oneCallable = new Tickets();        FutureTask oneTask = new FutureTask(oneCallable);        Thread t = new Thread(oneTask);        System.out.println(Thread.currentThread().getName());        t.start();    }}class Tickets implements Callable{    //重写call方法    @Override    public Object call() throws Exception {        // TODO Auto-generated method stub        System.out.println(Thread.currentThread().getName()+"-->我是通过实现Callable接口通过FutureTask包装器来实现的线程");        return null;    }   }


程序运行结果: 
main 
Thread-0–>我是通过实现Callable接口通过FutureTask包装器来实现的线程

线程实现方式4:通过线程池创建线程

public class ThreadDemo05{    private static int POOL_NUM = 10;     //线程池数量    /**     * @param args     * @throws InterruptedException      */    public static void main(String[] args) throws InterruptedException {        // TODO Auto-generated method stub        ExecutorService executorService = Executors.newFixedThreadPool(5);          for(int i = 0; i


程序运行结果: 
通过线程池方式创建的线程:pool-1-thread-3 
通过线程池方式创建的线程:pool-1-thread-4 
通过线程池方式创建的线程:pool-1-thread-1 
通过线程池方式创建的线程:pool-1-thread-5 
通过线程池方式创建的线程:pool-1-thread-2 
通过线程池方式创建的线程:pool-1-thread-5 
通过线程池方式创建的线程:pool-1-thread-1 
通过线程池方式创建的线程:pool-1-thread-4 
通过线程池方式创建的线程:pool-1-thread-3 
通过线程池方式创建的线程:pool-1-thread-2

ExecutorService、Callable都是属于Executor框架。返回结果的线程是在JDK1.5中引入的新特征,还有Future接口也是属于这个框架,有了这种特征得到返回值就很方便了。 
通过分析可以知道,他同样也是实现了Callable接口,实现了Call方法,所以有返回值。这也就是正好符合了前面所说的两种分类

执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了。get方法是阻塞的,即:线程无返回结果,get方法会一直等待。

再介绍Executors类:提供了一系列工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口。

public static ExecutorService newFixedThreadPool(int nThreads) 
创建固定数目线程的线程池。
public static ExecutorService newCachedThreadPool() 
创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。
public static ExecutorService newSingleThreadExecutor() 
创建一个单线程化的Executor。
public static ScheduledExecutorService newScheduledThreadPool(int 
corePoolSize) 
创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。
ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。

总结:

引用阿里的关于  线程的建议:


乐xenia
8楼 · 2020-10-19 18:08

1. 进程

进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。

2. 线程

线程是一条执行路径,是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。同样多线程也可以实现并发操作,每个请求分配一个线程来处理。

一个正在运行的软件(如迅雷)就是一个进程,一个进程可以同时运行多个任务( 迅雷软件可以同时下载多个文件,每个下载任务就是一个线程), 可以简单的认为进程是线程的集合。

线程是一条可以执行的路径。多线程就是同时有多条执行路径在同时(并行)执行。

3. 进程与线程的关系

一个程序就是一个进程,而一个程序中的多个任务则被称为线程。进程是表示资源分配的基本单位,又是调度运行的基本单位。,亦即执行处理机调度的基本单位。 进程和线程的关系:

  • 一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。线程是操作系统可识别的最小执行和调度单位。

  • 资源分配给进程,同一进程的所有线程共享该进程的所有资源。同一进程中的多个线程共享代码段(代码和常量),数据段(全局变量和静态变量),扩展段(堆存储)。但是每个线程拥有自己的栈段,栈段又叫运行时段,用来存放所有局部变量和临时变量,即每个线程都有自己的堆栈和局部变量。

  • 处理机分给线程,即真正在处理机上运行的是线程。

  • 线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

如果把上课的过程比作进程,把老师比作CPU,那么可以把每个学生比作每个线程,所有学生共享这个教室(也就是所有线程共享进程的资源),上课时学生A向老师提出问题,老师对A进行解答,此时可能会有学生B对老师的解答不懂会提出B的疑问(注意:此时可能老师还没有对A同学的问题解答完毕),此时老师又向学生B解惑,解释完之后又继续回答学生A的问题,同一时刻老师只能向一个学生回答问题(即:当多个线程在运行时,同一个CPU在某一个时刻只能服务于一个线程,可能一个线程分配一点时间,时间到了就轮到其它线程执行了,这样多个线程在来回的切换)

4. 为什么要使用多线程

多线程可以提高程序的效率。

实际生活案例:村长要求喜洋洋在一个小时内打100桶水,可以喜洋洋一个小时只能打25桶水,如果这样就需要4个小时才能完成任务,为了在一个小时能够完成,喜洋洋就请美洋洋、懒洋洋、沸洋洋,来帮忙,这样4只羊同时干活,在一小时内完成了任务。原本用4个小时完成的任务现在只需要1个小时就完成了,如果把每只羊看做一个线程,多只羊即多线程可以提高程序的效率。

5. 多线程应用场景

  • 一般线程之间比较独立,互不影响

  • 一个线程发生问题,一般不影响其它线程


相关问题推荐

  • 回答 156

    对于每一位才开始接触JAVA的新手来说,先不要管算法和数据结构,大多数简单的程序不需要用到算法和数据结构,所以当你真正需要时再去学习。编程一段时间以后,你就会知道在哪些地方用到他们。这时知道算法的名字并了解它们的功能,然后动手去实践。当我们在去...

  • 回答 93

    2个都很好就业,更关键的是要学得到东西

  • 回答 12
    已采纳

    获取Map集合中所有的key可以通过map集合的keySet()方法获取例如:    Map map = new HashMap();    map.put(xx,xx); //存放数据    //.... 省略    Set set = map.keySet();    //可以通过迭代器进行测试    Iterator iter = set.iter...

  • 回答 56
    已采纳

    不同年龄,不同掌握程度,学历,找工作城市,面试能力这是一个多方面影响的结果,如果是平均值的话,全国平均薪资14k左右

  • 回答 38

    具体学多久,根据自己的学习力,自律性、解决问题能力来决定若系统性学习,跟着讲师的节奏走,大概半年左右,有专业的讲师把课程进行规划,尽心系统学习,有问题,讲师会帮忙解决,学习的效率很高,避免了自学中出现各种问题解决不了,而耽误很多时间,可能会...

  • 回答 23
    已采纳

    (1)idea启动时会有两个快捷方式,安装完后默认生成在桌面的是32位的idea的快捷方式,如果我们使用这个快捷方式运行大项目,一般都会很卡。解决方法是找到idea的安装目录,然后进入bin文件夹,找到名称为idea64的应用程序,右键他生成桌面快捷方式。以后每次...

  • BIO与NIO、AIO的区别2020-05-19 15:59
    回答 4
    已采纳

    IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。一、BIO     在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信,默认情况下服务端需要...

  • Java方法的命名规则2021-04-06 19:07
    回答 31

    ava是一种区分字母的大小写的语言,所以我们在定义变量名的时候应该注意区分大小写的使用和一些规范,接下来我们简单的来讲讲Java语言中包、类、变量等的命名规范。(一)Package(包)的命名Package的名字应该都是由一个小写单词组成,例如com、xuetang9、compan...

  • 回答 2

    public class Point {    private int x;    private int y;    public int getX() {        return x;    }    public void setX(int x) {        this.x = x;    }    public int getY() {        return y;    } ...

  • 回答 6

    经典版单例模式public class Singleton {        private static Singleton uniqueInstance;//利用一个静态常量来记录singleton类的唯一实例。     private Singleton() {     }     public static  Singleton getInstance()...

  • 回答 3

    哈希表的长度一般是定长的,在存储数据之前我们应该知道我们存储的数据规模是多大,应该尽可能地避免频繁地让哈希表扩容。但是如果设计的太大,那么就会浪费空间,因为我们跟不用不到那么大的空间来存储我们当前的数据规模;如果设计的太小,那么就会很容易发...

  • 回答 14

    1. DOM(Document Object Model)        DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才...

  • 回答 19

    1)作用不同: throw用于程序员自行产生并抛出异常; throws用于声明在该方法内抛出了异常2) 使用的位置不同: throw位于方法体内部,可以作为单独语句使用; throws必须跟在方法参数列表的后面,不能单独使用。3)内容不同: throw抛出一个异常对象,且只能是...

  • 回答 11

    基本执行过程如下:1)程序首先执行可能发生异常的try语句块。2)如果try语句没有出现异常则执行完后跳至finally语句块执行;3)如果try语句出现异常,则中断执行并根据发生的异常类型跳至相应的catch语句块执行处理。4)catch语句块可以有多个,分别捕获不同类型...

  • 回答 20

    100-199 用于指定客户端应相应的某些动作。 200-299 用于表示请求成功。 300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息。 400-499 用于指出客户端的错误。 400 语义有误,当前请求无法被服务器理解。 401 当前请求需要用户验证...

  • 回答 16

    异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常就不会发生。受检异常跟程序运行的上下文环境有关,即使程序设计无误,仍然可能因使用的问题而引发。Java编译...

没有解决我的问题,去提问