热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

javathis多线程_java——多线程知识点大总结

1:理解线程的概念之前,我们有必要先理解一下进程的概念程序(Program)是为实现特定目标或解决特定问题而用计算机语言(比如Java语言)编写的命令序

1:理解线程的概念之前,我们有必要先理解一下进程的概念

程序(Program)是为实现特定目标或解决特定问题而用计算机语言(比如Java语言)编写的命令序列的集合。

进程指一个程序的一次执行过程

5a3dc7a3183ecdc4094eccc666575a3a.png     

2b9d608c1edad88213418fd48caec73c.png

947b2532eabaa3525fcf948d0b76cc25.png

2:线程

线程又称为轻量级进程,线程是一个程序中实现单一功能的一个指令序列,是一个程序的单个执行流,存在于进程中,是一个进程的一部分。线程不能单独运行,必须在一个进程之内运行。

48f7b10b445be8ed5f57ed17b54cb28f.png

dfab7c1a199520b61e42d61f80c6d21b.png

c26cc521bc0df99d1fd1dd147eda5206.png

8967f2e9dc01fee3d87d6ec2dbc25df9.png

572646d2edf62bdda8c91adc8ef78dae.png

线程的特点

667b33bfd95afb01be74de6817417023.png

线程和进程

d72e7e8c7319da18f807c8626b336b3b.png

如何自定义线程类

b099f993a5fc932f94d94de3251885d3.png

48de5536ca35b9967870d283c9151592.png

635af7432fcc949e66d7a705447d0466.png

线程中的进程

8b25f5636f202e27341b85f6ac335f6f.png

cf9080f99adf4f4e46c51a2fe173c0d4.png

c9c9aa9d951f003010326e36f8307894.png

线程中的常用方法

397131714e1848c3a65f73309fbd9052.png

importjava.util.Date;class TimeThread extendsThread{

&#64;Overridepublic voidrun() {for(int i&#61;0;i<&#61;2; i&#43;&#43;){

System.out.println("时间线程&#xff1a;"&#43;newDate());try{

Thread.sleep(10000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}class CounterThread extendsThread {privateTimeThread timeThread;publicCounterThread(TimeThread timeThread){this.timeThread &#61;timeThread;

}

&#64;Overridepublic voidrun() {for(int i&#61;1;i<&#61;3; i&#43;&#43;){if(i&#61;&#61;2){try{

timeThread.join();

}catch(InterruptedException e) {

e.printStackTrace();

}

}

System.out.println("计数器线程&#xff1a;"&#43;i);

}

}

}public classProgram {public static voidmain(String[] args) {

TimeThread timeThread&#61; newTimeThread();

timeThread.start();newCounterThread(timeThread).start();

}

}

注意&#xff1a;线程对象在调用join方法前必须先调用start方法&#xff0c;否则该线程永远不会进入执行状态。

828328ff3d68aa01f8a54a8fe1ea4d46.png

importjava.text.SimpleDateFormat;importjava.util.Date;class TimeThread extendsThread {public voidrun() {

SimpleDateFormat sdf&#61; new SimpleDateFormat("HH:mm:ss:sss");

String beforeTime&#61; sdf.format(newDate());

System.out.println("beforeTime&#xff1a;"&#43;beforeTime);try{

sleep(30000);//30秒后执行后面代码

} catch(Exception e) {

System.out.println("程序捕获了InterruptedException异常!");

}

String afterTime&#61; sdf.format(newDate());

System.out.println("afterTime&#xff1a;"&#43;afterTime);

}

}public classProgram {public static voidmain(String[] args) {

TimeThread timeThread&#61; newTimeThread();

timeThread.start();try{

Thread.sleep(1000);

}catch(InterruptedException e){

e.printStackTrace();

}

timeThread.interrupt();

}

}

9bf544676ae71f16c2adc530f529e0df.png

class CounterThread extendsThread {

Object lockObj;publicCounterThread(Object lockObj) {this.lockObj &#61;lockObj;

}

&#64;Overridepublic voidrun() {synchronized(lockObj) {

System.out.println("计数器线程正在执行......");try{

lockObj.wait();//当线程执行该行代码后&#xff0c;线程进入阻塞状态&#xff1b;但由于10秒后主线程执行了“counterThread.interrupt();”代码使得该线程阻塞状态结束

} catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}public classTest {public static voidmain(String[] args) {

Object lockObj&#61; newObject();

CounterThread counterThread&#61; newCounterThread(lockObj);

counterThread.start();try{

Thread.sleep(10000);

}catch(InterruptedException e) {

e.printStackTrace();

}

counterThread.interrupt();

}

}

importjava.util.Date;class TimeThread extendsThread{

&#64;Overridepublic voidrun() {for(int i&#61;0;i<&#61;2; i&#43;&#43;){

System.out.println("时间线程&#xff1a;"&#43;newDate());try{

Thread.sleep(10000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}class CounterThread extendsThread {privateTimeThread timeThread;publicCounterThread(TimeThread timeThread){this.timeThread &#61;timeThread;

}

&#64;Overridepublic voidrun() {for(int i&#61;1;i<&#61;3; i&#43;&#43;){if(i&#61;&#61;2){try{

timeThread.join();

}catch(InterruptedException e) {

System.out.println("计数器线程提前结束阻塞状态");

}

}

System.out.println("计数器线程&#xff1a;"&#43;i);

}

}

}public classProgram {public static voidmain(String[] args) {

TimeThread timeThread&#61; newTimeThread();

timeThread.start();

CounterThread counterThread&#61; newCounterThread(timeThread);

counterThread.start();try{

Thread.sleep(15000);

}catch(InterruptedException e) {

e.printStackTrace();

}

counterThread.interrupt();//计数器线程执行该行代码后进入阻塞状态&#xff0c;时间线程至少需要消耗30秒才能结束&#xff0c;而15秒后计数器线程调用了interrupt方法致使该计数器线程提前结束阻塞状态。

}

}

1453e58faee0163ab7968efe9d9bb8da.png

守护线程不是将原来线程改为守护线程&#xff0c;而是本来就是守护线程&#xff0c;别忘了setDaemon方法需要在start方法之前调用。

代码1&#xff1a;public classProgram {public static voidmain(String[] args) {

CounterThread counterThread&#61; newCounterThread();

counterThread.setDaemon(true);

counterThread.start();try{

Thread.sleep(1);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}class CounterThread extendsThread {public voidrun() {int i&#61;1;while(true){

System.out.println("计数器&#xff1a;"&#43;i);

i&#43;&#43;;

}

}

}

代码2&#xff1a;importjava.text.SimpleDateFormat;importjava.util.Date;/*** 线程中所启动的其他非守护线程线程不会随着该线程的结束而结束*/

public classThreadDead {public static voidmain(String[] args) {try{

Thread.sleep(10000);

}catch(InterruptedException e) {

e.printStackTrace();

}

TimeThread timeThread&#61; newTimeThread();

timeThread.start();//10秒后“任务管理器”中javaw.exe进程中线程数量会多一条

}

}class TimeThread extendsThread{

&#64;Overridepublic voidrun() {

SimpleDateFormat sdf&#61; new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

String currentTime&#61; sdf.format(newDate());

System.out.println("时间线程,当前时间&#xff1a;"&#43;currentTime);try{

Thread.sleep(10000);

}catch(InterruptedException e) {

e.printStackTrace();

}

CounterThread counterThread&#61; newCounterThread();//counterThread.setDaemon(true);

counterThread.start();//10秒后“任务管理器”中javaw.exe进程中线程数量会再多一条

try{

Thread.sleep(5000);//一个时段后“任务管理器”中javaw.exe进程中线程数量会少一条&#xff0c;但计数器线程依然在工作

} catch(InterruptedException e) {

e.printStackTrace();

}

}

}class CounterThread extendsThread {public voidrun() {int i&#61;1;while(true){

System.out.println("计数器线程&#xff1a;"&#43;i);

i&#43;&#43;;try{

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}

12c0d1674730bb831e84c1f9bada77a4.png

81b00c06a27eb69d3f0c7a08e45376ab.png

终止程序——无疾而终

classCounterThread extends Thread {private boolean flag &#61; true;public voidstopThread() {

flag&#61; false;

}public voidrun() {int i &#61; 0;while(flag) {

System.out.println("计数器线程&#xff1a;" &#43;i);

i&#43;&#43;;try{

sleep(5000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}public classProgram {public static voidmain(String[] args) {

CounterThread counterThread&#61; newCounterThread();

counterThread.start();try{

Thread.sleep(15000);//15秒后线程终止

counterThread.stopThread();

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

终止程序——暴毙死亡

classCounterThread extends Thread {

&#64;Overridepublic voidrun() {int i &#61; 0;try{while (true) {

System.out.println("计数器线程&#xff1a;" &#43;i);

i&#43;&#43;;

Thread.sleep(3000);

}

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}public classProgram {public static voidmain(String[] args) {

CounterThread counterThread&#61; newCounterThread();

counterThread.start();try{

Thread.sleep(1000);

}catch(InterruptedException e){

e.printStackTrace();

}

counterThread.interrupt();

}

}

上面CounterThread类不可这样写&#xff1a;classCounterThread extends Thread {

&#64;Overridepublic voidrun() {int i&#61;0;while(true){

System.out.println("计数器线程&#xff1a;"&#43;i);

i&#43;&#43;;try{

Thread.sleep(3000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}

串行运行

a56700a358a9139c342a3c5621e61f22.png

代码1&#xff1a;public classTest {private static Object shareData &#61; new Object();//多线程间共享的数据

public static voidmain(String[] args) {new CounterThread("线程1",shareData).start();new CounterThread("线程2",shareData).start();

}

}classCounterThread extends Thread{privateObject shareData;publicCounterThread(String threadName,Object shareData){

super(threadName);this.shareData &#61;shareData;

}

&#64;Overridepublic voidrun() {

synchronized (shareData) {for (int i &#61; 0; i <3; i&#43;&#43;) {

System.out.println(getName() &#43; ":" &#43;i);

}

}

}

}

代码2&#xff1a;public classTest {public static voidmain(String[] args) {new CounterThread("线程1").start();new CounterThread("线程2").start();

}

}classCounterThread extends Thread {publicCounterThread(String threadName) {

super(threadName);

}

&#64;Overridepublic voidrun() {

synchronized (CounterThread.class) {//执行代码3可知道为什么这样做也可以

for (int i &#61; 0; i <3; i&#43;&#43;) {

System.out.println(getName() &#43; ":" &#43;i);

}

}

}

}

代码3&#xff1a;public classTest {public static voidmain(String[] args){

System.out.println(Test.class &#61;&#61; Test.class);

}

}

线程之间数据共享——并行运行

多个线程之间默认并发运行&#xff0c;这种运行方式往往会出现交叉的情况

fb6ab48cd900bdbecdb792dc54ec9244.png

0776fe29a9d6d3ae4211e9fa1a6a0dd8.png

ae4ef16886d31f907609a7266e0c7233.png

线程之间数据共享——串行运行(synchronized)

使原本并发运行的多个线程实现串行运行&#xff0c;即多线程间同步执行&#xff0c;需要通过对象锁机制来实现&#xff0c;synchronized就是一个利用锁实现线程同步的关键字。

00e17f14f77c4c8a716005200c080baf.png

068a69a931117e63a3e216ee2dcc7d89.png

b070d3184ea7ed9fe87d1925dd03c9b3.png

多线程同步原理

为什么通过synchronized就能实现多线程间串行运行呢&#xff1f;

被synchronized括着的部分就是线程执行临界区&#xff0c;每次仅能有一个线程执行该临界区中的代码&#xff1a;当多个线程中的某个线程先拿到对象锁&#xff0c; 则该线程执行临界区内的代码&#xff0c;其他线程只能在临界区外部等待&#xff0c;当此线程执行完临界区中的代码后&#xff0c;在临界区外部等待的其他线程开始再次竞争以获取对象锁&#xff0c;进而执行临界区中的代码&#xff0c;但只能有一条线程“胜利”。

临界区中的代码具有互斥性、唯一性和排它性&#xff1a;一个线程只有执行完临界区中的代码另一个线程才能执行。

1 packagecom.xt.two;2 import java.text.*;3 importjava.util.Date;4

5 public classSynTest {6

7 public static voidmain(String[] args) {8 Object lockObj &#61; newObject();9 newDisplayThread(lockObj).start();10 }11 }12

13 class DisplayThread extendsThread {14

15 Object lockObj;16

17 publicDisplayThread(Object lockObj) {18 this.lockObj &#61;lockObj;19 }20

21 &#64;Override22 public voidrun() {23 synchronized(lockObj) {24 newTimeThread(lockObj).start();25 try{26 sleep(60000);27 } catch(InterruptedException e) {28 e.printStackTrace();29 }30 }31 }32 }33 class TimeThread extendsThread {34

35 Object lockObj;36

37 publicTimeThread(Object lockObj) {38 this.lockObj &#61;lockObj;39 }40

41 &#64;Override42 public voidrun() {43 System.out.println("时间线程开始执行......");44 synchronized(lockObj) {45 DateFormat dateFormat &#61; new SimpleDateFormat("HH:mm:ss");46 String time &#61; dateFormat.format(newDate());47 System.out.println(time);

//为什么这行代码60秒左右才会执行&#xff1f;48 //显示器线程和时间线程共享lockObj对象&#xff0c;显示器线程优先进入启动状态&#xff0c;随后执行相应的run方法&#xff0c;当执行同步代码块时lockObj变量所代表的对象锁归显示器线程所有&#xff0c;49 //进而创建时间线程并使之处于启动状态&#xff0c;此时有一下两种状态&#xff1a;50 //1、时间线程马上进入执行状态&#xff0c;51 //马上执行该时间线程run方法,可是由于此时lockObj变量所代表的对象锁被显示器线程持有&#xff0c;52 //这时时间线程进入阻塞状态&#xff0c;显示器线程再次执行&#xff0c;然后执行sleep方法&#xff0c;显示器线程在继续持有对象锁的前提下53 //也进入阻塞状态&#xff0c;60秒后显示器线程进入执行状态&#xff0c;随后显示器线程结束&#xff0c;对象锁被释放&#xff0c;进而时间线程开始执行&#xff0c;进而这行代码运行&#xff1b;54 //2、时间线程并没有马上进入执行状态&#xff0c;显示器线程执行sleep方法&#xff0c;显示器线程在继续持有对象锁的前提下55 //也进入阻塞状态&#xff0c;此时时间线程进入执行状态&#xff0c;执行该时间线程run方法,执行该方法中第一行输出代码&#xff0c;56 //可是由于此时lockObj变量所代表的对象锁被显示器线程持有&#xff0c;57 //所以时间线程并没有执行时间线程run方法内临界区中的代码,这时时间线程也进入阻塞状态&#xff0c;此时显示器和时间两条线程均进去阻塞状态&#xff0c;58 //等待少于60秒的时间后&#xff0c;显示器线程进入运行状态&#xff0c;随后显示器线程结束&#xff0c;对象锁被释放&#xff0c;进而时间线程开始执行&#xff0c;进而这行代码运行&#xff1b;

59 }60 }61 }

synchronized(this)

public classTest {public static voidmain(String[] args) {new CounterThread("线程1").start();new CounterThread("线程2").start();

}

}class CounterThread extendsThread{publicCounterThread(String threadName){super(threadName);

}

&#64;Overridepublic voidrun() {synchronized (this) {//此时临界区中的代码无法实现串行执行&#xff0c;因为此时对象锁在线程1和线程2之间不共享

for (int i &#61; 0; i <3; i&#43;&#43;) {

System.out.println(getName()&#43; " : " &#43;i);

}

}

}

}

public classTest {public static voidmain(String[] args) {new Thread(new CounterThread(),"线程1").start();new Thread(new CounterThread(),"线程2").start();

}

}class CounterThread implementsRunnable {

&#64;Overridepublic voidrun() {synchronized (this) {//此时临界区中的代码依然无法实现串行执行&#xff0c;因为每一个独立线程拥有一个独立的锁对象——new CounterThread()。//要明白这两点&#xff1a;//谁调用该run方法&#xff1f;——CounterThread类对象&#xff1b;//谁执行该run方法&#xff1f;——正在执行的线程

Thread thread &#61;Thread.currentThread();for (int i &#61; 0; i <3; i&#43;&#43;) {

System.out.println(thread.getName()&#43; ":" &#43;i);

}

}

}

}

public classTest {public static voidmain(String[] args) {

Runnable counterThread&#61; newCounterThread();new Thread(counterThread,"线程1").start();new Thread(counterThread,"线程2").start();

}

}class CounterThread implementsRunnable {

&#64;Overridepublic voidrun() {synchronized (this) {//此时临界区中的代码可以实现串行执行&#xff0c;因为此时接口实现类对象充当了对象锁的功能&#xff0c;该对象锁在两个线程之间共享

Thread thread &#61;Thread.currentThread();for (int i &#61; 0; i <3; i&#43;&#43;) {

System.out.println(thread.getName()&#43; ":" &#43;i);

}

}

}

}

线程死锁

如果有两个或两个以上的线程都访问了多个资源&#xff0c;而这些线程占用了一些资源的同时又在等待其它线程占用的资源&#xff0c;也就是说多个线程之间都持有了对方所需的资源&#xff0c;而又相互等待对方释放的资源&#xff0c;在这种情况下就会出现死锁。 多个线程互相等待对方释放对象锁&#xff0c;此时就会出现死锁

public classDeadLockThread {//创建两个线程之间竞争使用的对象

private static Object lock1 &#61; newObject();private static Object lock2 &#61; newObject();public static voidmain(String[] args) {newShareThread1().start();newShareThread2().start();

}private static class ShareThread1 extendsThread {public voidrun() {synchronized(lock1) {try{

Thread.sleep(50);

}catch(InterruptedException e) {

e.printStackTrace();

}synchronized(lock2) {

System.out.println("ShareThread1");

}

}

}

}private static class ShareThread2 extendsThread {public voidrun() {synchronized(lock2) {try{

Thread.sleep(50);

}catch(InterruptedException e) {

e.printStackTrace();

}synchronized(lock1) {

System.out.println("ShareThread2");

}

}

}

}

}

线程协作

importjava.text.SimpleDateFormat;importjava.util.Date;public classElectronicWatch {

String currentTime;public static voidmain(String[] args) {new ElectronicWatch().newDisplayThread().start();

}/*** 该线程负责显示时间*/

class DisplayThread extendsThread{

&#64;Overridepublic voidrun() {newTimeThread ().start();

System.out.println(currentTime);//为什么结果可能为null

}

}/*** 该线程负责获取时间*/

class TimeThread extendsThread{

&#64;Overridepublic voidrun() {try{

sleep(3000);

}catch(InterruptedException e) {

e.printStackTrace();

}

String pattern&#61; "yyyy-MM-dd HH:mm:ss";

SimpleDateFormat sdf&#61; newSimpleDateFormat(pattern);

currentTime&#61; sdf.format(newDate());

}

}

}

代码2&#xff1a;packagetest;importjava.text.SimpleDateFormat;importjava.util.Date;public classElectronicWatch {

String currentTime;public static voidmain(String[] args) {new ElectronicWatch().newDisplayThread().start();

}/*** 该线程负责显示时间*/

class DisplayThread extendsThread{

&#64;Overridepublic voidrun() {

TimeThread timeThread&#61; newTimeThread();

timeThread.start();try{

sleep(5000);//这种方式不可取&#xff1a;这种方式性能不高

} catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println(currentTime);

}

}/*** 该线程负责获取时间*/

class TimeThread extendsThread{

&#64;Overridepublic voidrun() {try{

sleep(3000);

}catch(InterruptedException e) {

e.printStackTrace();

}

String pattern&#61; "yyyy-MM-dd HH:mm:ss";

SimpleDateFormat sdf&#61; newSimpleDateFormat(pattern);

currentTime&#61; sdf.format(newDate());

}

}

}

代码3&#xff1a;packagetest;importjava.text.SimpleDateFormat;importjava.util.Date;public classElectronicWatch {

String currentTime;public static voidmain(String[] args) {new ElectronicWatch().newDisplayThread().start();

}/*** 该线程负责显示时间*/

class DisplayThread extendsThread{

&#64;Overridepublic voidrun() {

TimeThread timeThread&#61; newTimeThread();

timeThread.start();try{

timeThread.join();

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println(currentTime);

}

}/*** 该线程负责获取时间*/

class TimeThread extendsThread{

&#64;Overridepublic voidrun() {try{

sleep(3000);

}catch(InterruptedException e) {

e.printStackTrace();

}

String pattern&#61; "yyyy-MM-dd HH:mm:ss";

SimpleDateFormat sdf&#61; newSimpleDateFormat(pattern);

currentTime&#61; sdf.format(newDate());

}

}

}

代码4&#xff1a;wait和notify方法

packagecom.xt.two;importjava.text.SimpleDateFormat;importjava.util.Date;public classElectronicWatch {

String currentTime;public static Object obj &#61; newObject();public static voidmain(String[] args) {new ElectronicWatch().newDisplayThread(obj).start();

}/*** 该线程负责显示时间*/

class DisplayThread extendsThread{

Object obj;publicDisplayThread(Object obj) {this.obj &#61;obj;

}

&#64;Overridepublic voidrun() {

TimeThread tt&#61;newTimeThread (obj);

tt.start();synchronized(obj) {try{

obj.wait();

}catch(InterruptedException e) {

e.printStackTrace();

}

}

System.out.println(currentTime);//为什么结果可能为null

}

}/*** 该线程负责获取时间*/

class TimeThread extendsThread{

Object obj;publicTimeThread(Object obj) {this.obj &#61;obj;

}

&#64;Overridepublic voidrun() {try{

sleep(3000);

}catch(InterruptedException e) {

e.printStackTrace();

}

String pattern&#61; "yyyy-MM-dd HH:mm:ss";

SimpleDateFormat sdf&#61; newSimpleDateFormat(pattern);

currentTime&#61; sdf.format(newDate());synchronized(obj) {

obj.notify();

}

}

}

}



推荐阅读
  • Java自带的观察者模式及实现方法详解
    本文介绍了Java自带的观察者模式,包括Observer和Observable对象的定义和使用方法。通过添加观察者和设置内部标志位,当被观察者中的事件发生变化时,通知观察者对象并执行相应的操作。实现观察者模式非常简单,只需继承Observable类和实现Observer接口即可。详情请参考Java官方api文档。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • Spring学习(4):Spring管理对象之间的关联关系
    本文是关于Spring学习的第四篇文章,讲述了Spring框架中管理对象之间的关联关系。文章介绍了MessageService类和MessagePrinter类的实现,并解释了它们之间的关联关系。通过学习本文,读者可以了解Spring框架中对象之间的关联关系的概念和实现方式。 ... [详细]
  • 数组的排序:数组本身有Arrays类中的sort()方法,这里写几种常见的排序方法。(1)冒泡排序法publicstaticvoidmain(String[]args ... [详细]
author-avatar
让爱自由2009
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有