JavaSE学习笔记_10:Java多线程

JavaSE多线程 编写一个类,直接继承java. lang. Thread,重写run方法 阅读详情

Java多线程

 

1、线程概述

我们都知道进程,进程是一个正在执行的程序。如qq,酷狗等,是一个明确的概念。而线程就是进程中的一个独立的控制单元或者叫做一个独立的执行路径,控制着进程的执行,线程包含在进程当中,是一个抽象概念。

 

一个进程中至少有一个线程。

 

我们知道:cpu在不同进程中快速切换,更具体地说,cpu在不同的线程中快速切换。我们现在以一个进程当中有多个线程来学习。多个线程都获取cpu的执行权,cpu执行到谁,或者说被谁抢到,谁就执行,执行多长时间cpu说了算。因此某一个时刻,只能有一个程序在运行(多核除外)。cpu在做着快速的切换,以达到看上去同时运行的效果。cpu切换具有随机性。

 

java也有两个进程:编译进程javac.exe、运行进程java.exe。

class Demo

{

public static void main(String[] args)

{

System.out.println(“hello world”);

}

}

java.exe进程启动后会使jvm启动,jvm就开始执行程序,

像这样一个简单的程序,就只有一个线程负责java程序的执行。而且这个线程运行的代码存在于main()中。该线程称之为主线程。其实,jvm启动的应该不止这一个线程,还有负责垃圾回收的线程。这样效率才高。

 

 

为什么一个程序中需要有多个线程来分工控制执行?

一个程序当中肯定会涉及到外设的工作,因此,当需要外设工作时,线程就应该释放cpu资源,让其他线程使用,那么cpu资源没有浪费,还是在执行这个程序的其他部分。如果是单线程,需要外设工作时,线程就会等待外设工作完以后才继续向下执行,cpu闲置浪费资源。因此完成程序执行的时间拉长,效率低。这就跟多个人配合起来做一件事,效率高是一回事。

 

2、创建线程

(1)第一种方式:继承Thread类

① 定义类继承Thread类。

② 复写Thread类中的run方法。

③ 调用创建对象调用start方法。

Ps:注意区别run()和start()。

start():开启线程并执行该线程的run方法。一个线程只能开启一次。

run():仅仅是对象调用的方法。存放线程要执行的代码。

 

(2)第二种方式:实现Runnable接口

① 定义类实现Runnable接口。

② 覆盖Runnable接口中的run方法,该方法也是存放线程要执行的代码。

③ 通过Thread类建立线程对象。

④ 将Runnable接口的子类对象作为实际参数作为实际参数传递给Thread类的构造函数。

⑤ 调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。

 

 

线程的几种状态:

 

 

练习:创建两个线程,和主线程交替运行。x是独有数据。

class Test extends Thread

{

private String name;

Test(String)

{

This.name=name;

}

public void run()

{

for(int x=0;x<60;x++)

{

System.out.println(name+”run--”+x);

}

}

}

class ThreadTest

{

public static void main(String[] args)

{

Test t1=new Test(“one”);

Test t2=new Test(“two”);

}

t1.start();

t2.start();

for(int x=0;x<60;x++)

{

System.out.println(“main---”+x);

}

}

 

线程都有自己的默认的名称:

Thread-编号,该编号从0开始。

也可以自定义名称:

Thread 

{

private String name;

Thread(String name)

{

This.name=name;

}

public String getName()

{

return name;

}

}

class Test extends Thread

{

Test(String name)

{

super(name);

}

}

Thread类中还有一个静态方法currentThread(),返回当前正在执行的线程对象的引用。this.getName()=Thread.currentThread().getName()

 

 

 

通过售票的例子来讲解两种创建线程方法的不同:

需求:简单的买票程序。多个窗口卖票。(多线程)票数是共享数据。

class Ticket extends Thread

{

private static int tick=100;

public void run()

{

while(true)

{

if(tick>=0)

{

System.out.println();

}

}

}

}

Class TicketDemo

{

Public static void main(String[] args)

{

Ticket t1=new Ticket();

Ticket t2=new Ticket();

Ticket t3=new Ticket();

Ticket t4=new Ticket();

 

t2.start();

t3.start();

t4.start();

t5.start();

}

}

但是,static变量生命周期过长。因此换一种方式:

class Ticket implements Runnable

{

private int tick=100;

public void run()

{

while(true)

{

if(tick<0)

{

System.out.println(

Thread.currentThread().getName()+”...sale:”+tick--);

}

}

}

}

class TicketDemo

{

public static void main(String[] args)

{

Ticket t=new Ticket();

 

Thread t1=new Thread(t);

Thread t2=new Thread(t);

Thread t3=new Thread(t);

Thread t4=new Thread(t);

 

t2.start();

t3.start();

t4.start();

t5.start();

 

}

}

因此:开发时都建立使用第二种方式。

 

3、多线程的安全问题

看图说话:

 

用程序来模拟这种情况:

class Ticket implements Runnable

{

private int tick=100;

public void run()

{

//线程抢来资源,cpu允许其执行一段时间,因此用用 //循环,让它可以执行多次。

while(true)

{

if(tick<0)

{

try{Thread.sleep(10);}catch(Exception e){}

System.out.println(

Thread.currentThread().getName()+”...sale:”+tick--);

}

}

}

}

/*

一个线程进来以后,睡了10秒钟进入了冻结状态,该线程就不具备执行资格,释放了cpu资源。其他线程抢到了,进来以后,发生了同样的情况。当他们醒来以后,进入了临时状态,随后进入运行状态,就不在判断if条件了直接往下执行。假设它们醒来之前tick的值为2,则醒后分别打印2,1,-1,0。则打印了错票,产生了安全问题。

*/

class TicketDemo

{

public static void main(String[] args)

{

Ticket t=new Ticket();

 

Thread t1=new Thread(t);

Thread t2=new Thread(t);

Thread t3=new Thread(t);

Thread t4=new Thread(t);

 

t2.start();

t3.start();

t4.start();

t5.start();

 

}

}

 

产生安全问题的原因:共享数据

当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行。导致数据的错误。

 

安全问题的解决办法:同步

同步有两种形式:

同步代码块、同步函数

同步代码块:

Sysnchronized(对象)

{

需要被同步的代码。

}

 

同步函数:

在函数返回值类型前面加上关键字:synchronized。

(1)非静态同步函数

它使用的锁是this。(函数需要被对象调用。那么函数都有一个所属对象的引用。就是this,因此为了满足使用同一个锁,同步函数使用的锁是this。)

(2)静态同步函数

它使用的锁是所在类的类文件。(静态进内存时,内存中没有本类对象,但是一定有该类文件对应的字节码文件对象。类名.class,该对象的类型是class)

 

解决售票的这个安全问题可以用同步代码块:

class Ticket implements Runnable

{

private int tick=100;

public void run()

{

while(true)

{

//锁直接用Object类,省得再定义类了。

Synchronized(new Object())

{

if(tick<0)

{

try{Thread.sleep(10);}catch(Exception e){}

System.out.println(

Thread.currentThread().getName()+”...sale:”+tick--);

}

}

}

}

}

class TicketDemo

{

public static void main(String[] args)

{

Ticket t=new Ticket();

 

Thread t1=new Thread(t);

Thread t2=new Thread(t);

Thread t3=new Thread(t);

Thread t4=new Thread(t);

 

t2.start();

t3.start();

t4.start();

t5.start();

}

}

解决售票的这个安全问题也可以用同步函数:

class Ticket implements Runnable

{

private int tick=100;

public void run()

{

while(true)

{

show();

}

}

public synchronized void show()

{

if(tick<0)

{

try{Thread.sleep(10);}catch(Exception e){}

System.out.println(

Thread.currentThread().getName()+”...sale:”+tick--);

}

}

}

class TicketDemo

{

public static void main(String[] args)

{

Ticket t=new Ticket();

 

Thread t1=new Thread(t);

Thread t2=new Thread(t);

Thread t3=new Thread(t);

Thread t4=new Thread(t);

 

t2.start();

t3.start();

t4.start();

t5.start();

}

}

 

 

同步的前提:

a. 必须要有两个或者两个以上的线程。

b. 必须是多个线程使用同一个锁。主要是指将需要同步的代码分成了两处,每一处都不只一条语句,一处用了同步代码块,一处用了同步函数,此时锁是this;还有就是线程通信中两个实现Runnable接口的子类中run()操作共享数据时(此时应该叫同一资源更合适)分别有多条语句且被同步,两处的锁也必须是同一个锁,通常这个锁都是资源类Res对象。

 

Ps:前提是加了同步一定安全的重要依据。加了同步,还有安全问题,就要看是否遵循了这两个前提。

 

同步的好处和弊端:

好处:解决了多线程的安全问题。

弊端:多个线程需要判断锁,较为消耗资源。

 

多线程安全问题的解决思路:

(1)找到问题

① 明确哪些代码是多线程运行代码。

② 明确共享数据。

③ 明确多线程运行代码中那些语句是操作共享数据的。这些语句就是需要被同步的代码。

(2)解决问题

 用同步

 

4、死锁

死锁:同步中嵌套同步。

(面试)

class MyLock

{

static Object locka=new Object();

static Object lockb=new Object();

}

class Test implements Runnable

{

private boolean flag;

Test(boolean flag)

{

This.flag=flag;

}

public void run()

{

if(flag)

{

while(true)

{

synchronized(MyLock.locka)

{

system.out.println(

Thread.currentThread().getName()+”...if locka”)

synchronized(Mylock.lockb)

{

system.out.println(

Thread.currentThread().getName()+”...if lockb”)

 

}

}

}

}

else

{

while(true)

{

synchronized(MyLock.lockb)

{

System.out.println(

Thread.currentThread().getName()+”...else lockb”)

synchronized(Mylock.locka)

{

System.out.println(

Thread.currentThread().getName()+”...else locka”)

}

}

}

}

}

class DeadLockTest

{

public static void main(String[] args)

{

Thread t1=new Thread(new Test(true));

Thread t2=new Thread(new Test(flase));

t1.start();

t2.start();

}

}

 

 

 

5、线程间通信

多个线程动作不一致,执行代码不一样。两个类,两个run()。

比如:

 

线程间通信:

其实就是多个线程在操作同一个资源。

但是操作的动作相反。

 

示例:

class Res

{

String name;

String sex;

}

class Input implements Runnable

{

private Res r;

Input(Res r)

{

this.r=r;

}

public void run()

{

int x=0;

while(true)

{

if(x==0)

{

r.name=”mike”;

r.sex=”man”;

}

else

{

r.name=”丽丽”;

r.sex=”女女”;

}

x=(x+1)%2;

}

}

}

class Output implements Runnable

{

private Res r;

Output(Res r)

{

this.r=r;

}

public void run()

{

while(true)

{

System.out.println(r.name+”...”+r.sex);

}

}

}

class InputOutputDemo

{

public static void main(String[] args)

{

res r=new Res();

 

Input in=new Input(r);

Output out=new Output(r);

 

Thread t1=new Thread(in);

Thread t2=new Thread(out);

 

t1.start();

t2.start();

}

}

同样,它也会产生安全问题:存完姓名,还没来得及存性别,资源就被输出线程抢走,导致打印信息不对称:(男姓名,女性别)。因此也必须用同步来解决。

如下:

class Res

{

String name;

String sex;

}

class Input implements Runnable

{

private Res r;

Input(Res r)

{

this.r=r;

}

public void run()

{

int x=0;

while(true)

{

Synchronized(r)

{

if(x==0)

{

r.name=”mike”;

r.sex=”man”;

}

else

{

r.name=”丽丽”;

r.sex=”女女”;

}

x=(x+1)%2;

}

}

}

}

class Output implements Runnable

{

private Res r;

Output(Res r)

{

this.r=r;

}

public void run()

{

while(true)

{

synchronized(r)

{

System.out.println(r.name+”...”+r.sex);

}

}

}

}

class InputOutputDemo

{

public static void main(String[] args)

{

res r=new Res();

 

Input in=new Input(r);

Output out=new Output(r);

 

Thread t1=new Thread(in);

Thread t2=new Thread(out);

 

t1.start();

t2.start();

}

}

打印的效果不是很爽,原因是:cpu切换造成的,cpu资源时刻分配随机,且执行多长时间不定。输入线程获得cpu执行权后,可能会执行一段时间,那么在这段时间内就有可能存多次数据,且数据被覆盖存储,值为最后一次存的值。对于输出线程亦是如此。现在想存一次打印一次。

则:

 

代码如下:

class Res

{

String name;

String sex;

private boolean flag=false;

}

class Input implements Runnable

{

private Res r;

Input(Res r)

{

this.r=r;

}

public void run()

{

int x=0;

while(true)

{

Synchronized(r)

{

if(r.flag)

try{r.wait();}catch(Exception e){}

if(x==0)

{

r.name=”mike”;

r.sex=”man”;

}

else

{

r.name=”丽丽”;

r.sex=”女女”;

}

x=(x+1)%2;

r.flag=true;

r.notify();

}

}

}

}

class Output implements Runnable

{

private Res r;

Output(Res r)

{

this.r=r;

}

public void run()

{

while(true)

{

synchronized(r)

{

if(!r.flag)

try{r.wait();}catch(Exception e){}

System.out.println(r.name+”...”+r.sex);

r.flag=flag;

r.notify();

}

}

}

}

class InputOutputDemo

{

public static void main(String[] args)

{

res r=new Res();

 

Input in=new Input(r);

Output out=new Output(r);

 

Thread t1=new Thread(in);

Thread t2=new Thread(out);

 

t1.start();

t2.start();

}

}

代码优化:

class Res

{

String name;

String sex;

private boolean flag=false;

 

public synchronized void set(String name,String sex)

{

if(flag)

try{this.wait();}catch(Exception e){}

this.name=name;

this.sex=sex;

flag=true;

this.notify();

}

 

public synchronized void out()

{

if(!r.flag)

try{r.wait();}catch(Exception e){}

System.out.println(r.name+”...”+r.sex);

flag=false;

this.notify();

 

}

}

class Input implements Runnable

{

private Res r;

Input(Res r)

{

this.r=r;

}

public void run()

{

int x=0;

while(true)

{

 

if(x==0)

{

r.set(“mike”,”man”);

}

else

{

r.set(“丽丽”,”女女”);

}

x=(x+1)%2;

}

}

}

}

class Output implements Runnable

{

private Res r;

Output(Res r)

{

this.r=r;

}

public void run()

{

while(true)

{

r.out();

      }

}

}

}

class InputOutputDemo

{

public static void main(String[] args)

{

res r=new Res();

 

Input in=new Input(r);

Output out=new Output(r);

 

Thread t1=new Thread(in);

Thread t2=new Thread(out);

 

t1.start();

t2.start();

}

}

拓展:现在有多个输出线程,多个输入线程。

class Res

{

String name;

String sex;

private boolean flag=false;

 

public synchronized void set(String name,String sex)

{

if(flag)

try{this.wait();}catch(Exception e){}

this.name=name;

this.sex=sex;

flag=true;

this.notify();

}

 

public synchronized void out()

{

if(!r.flag)

try{r.wait();}catch(Exception e){}

System.out.println(r.name+”...”+r.sex);

flag=false;

this.notify();

 

}

}

class Input implements Runnable

{

private Res r;

Input(Res r)

{

this.r=r;

}

public void run()

{

int x=0;

while(true)

{

 

if(x==0)

{

r.set(“mike”,”man”);

}

else

{

r.set(“丽丽”,”女女”);

}

x=(x+1)%2;

}

}

}

}

class Output implements Runnable

{

private Res r;

Output(Res r)

{

this.r=r;

}

public void run()

{

while(true)

{

r.out();

      }

}

}

}

class InputOutputDemo

{

public static void main(String[] args)

{

res r=new Res();

 

Input in=new Input(r);

Output out=new Output(r);

 

Thread t1=new Thread(in);

Thread t2=new Thread(in);

 

Thread t3=new Thread(out);

Thread t4=new Thread(out);

 

t1.start();

t2.start();

t3.start();

t4.start();

 

}

}

说明:

如果t1线程先获得cpu执行权,则输入一次,将资源置为非空,唤醒等待线程池中的头一个线程,虽然此时没有需要唤醒的线程,然后进入等待状态;然后t2线程获得cpu执行权,由于资源非空,则不产生,也进入等待状态;然后t3线程获得cpu执行权,输出一次,将资源置为空,唤醒等待线程池中的头一个线程t1,t1从进入等待的那个地方醒过来,不再判断if条件,继续向下执行,输入一次数据,将资源置为非空,唤醒等待线程池中的头一个线程t2,t2也从进入等待的那个地方醒过来,不再判断if条件,继续向下执行,输入一次数据,注意这次将醒来的t1线程输入的数据覆盖掉了,导致漏打。所以进程醒来还需在判断if条件。所以将if改成while。但是如果这样,按照之前的唤醒机制,每次只唤醒一个,最后可能会导致所有进程都进入了等待状态。(冻结状态也称之为中断状态)因此还应该将notify()改成notifyAll()。

代码如下:

class Res

{

String name;

String sex;

private boolean flag=false;

 

public synchronized void set(String name,String sex)

{

while(flag)

try{this.wait();}catch(Exception e){}

this.name=name;

this.sex=sex;

flag=true;

this.notifyAll();

}

 

public synchronized void out()

{

while(!r.flag)

try{r.wait();}catch(Exception e){}

System.out.println(r.name+”...”+r.sex);

flag=false;

this.notifyAll();

 

}

}

class Input implements Runnable

{

private Res r;

Input(Res r)

{

this.r=r;

}

public void run()

{

int x=0;

while(true)

{

 

if(x==0)

{

r.set(“mike”,”man”);

}

else

{

r.set(“丽丽”,”女女”);

}

x=(x+1)%2;

}

}

}

}

class Output implements Runnable

{

private Res r;

Output(Res r)

{

this.r=r;

}

public void run()

{

while(true)

{

r.out();

      }

}

}

}

class InputOutputDemo

{

public static void main(String[] args)

{

res r=new Res();

 

Input in=new Input(r);

Output out=new Output(r);

 

Thread t1=new Thread(in);

Thread t2=new Thread(in);

 

Thread t3=new Thread(out);

Thread t4=new Thread(out);

 

t1.start();

t2.start();

t3.start();

t4.start();

 

}

}

线程间通信jdk5.0升级版:

上述中notifyAll()不仅唤醒了对方进程,也唤醒了本方进程。现在我们想只唤醒对方线程,升级版做到了这一点,依据:不可以对不同锁中的线程进行唤醒。

升级后:没有了synchronized,和wait()、notifyAll()、notify()。

有了Lock、Condition两个类。

Lock中有:lock()、unlock()

Condition中有:await()、signal()

 

代码如下:

class Res

{

String name;

String sex;

private boolean flag=false;

private Lock lock=new ReentrantLock();

private Condition condition-in=lock.newCondition();

private Condition condition-out=lock.newCondition();

 

 

public  void set(String name,String sex)

throws InterruptedException

{

Lock.lock();

Try

{

while(flag)

condition-in.await();

this.name=name;

this.sex=sex;

flag=true;

condition-out.signal();

}

Finally

{

Lock.unlock();

}

}

 

public void out()

throws InterruptedException

{

Lock.lock();

try

{

while(!r.flag)

condition-out.await();

System.out.println(r.name+...+r.sex);

flag=false;

condition-in.signal();

}

finally

{

Lock.unlock();

}

 

}

}

class Input implements Runnable

{

private Res r;

Input(Res r)

{

this.r=r;

}

public void run()

{

int x=0;

while(true)

{

try

{

if(x==0)

{

r.set(mike,man);

}

else

{

r.set(丽丽女女);

}

x=(x+1)%2;

}

catch(Exception e)

{

}

}

}

}

class Output implements Runnable

{

private Res r;

Output(Res r)

{

this.r=r;

}

public void run()

{

while(true)

{

try

{

r.out();

}

catch(Exception e)

{

}

}

}

}

class InputOutputDemo

{

public static void main(String[] args)

{

res r=new Res();

 

Input in=new Input(r);

Output out=new Output(r);

 

Thread t1=new Thread(in);

Thread t2=new Thread(in);

 

Thread t3=new Thread(out);

Thread t4=new Thread(out);

 

t1.start();

t2.start();

t3.start();

}

}

 

6、线程中常用方法

(1)停止线程

① stop(),但已经过时。

② 让run()结束。run()中有循环代码,通过一个标记控制循环条件。特殊情况:当线程处于冻结状态,就读不到标记,线程就不能结束,停在那,此时用Thread类中interrupt()方法,通过线程对象调用,让线程活过来,那么就可以读到标记,让run()结束,即让线程结束。

 

 

(2)守护线程

守护线程:后台线程。

开启后和前台线程共同抢夺cpu执行权,运行、开启都没有区别,就结束有区别。当所有的前台线程都结束后,后台线程自动结束。将线程设置为守护线程:在开启之前,线程对象.setDaemon(true);即可。这样可用在停止线程中。(可与解决:结束run()的第二种方式中所遇到的特殊情况)

 

(3)join方法

Public final void join()throws InterruptedException

{

 

}

当A线程执行到了B线程的.join()时,A就会等待,等B线程都执行完,A才会执行(受这种影响的只有A)。Join可以用来临时加入线程执行。

 

(4)优先级

抢cpu资源的频率高低。

set priority(int newPriority):更改线程的优先级。所有线程的默认优先级是5.

 

如:

static final int MAX_PRIORITY:线程可以具有的最高优先级:10;

static final int MiN_PRIORITY:线程可以具有的最小优先级:1;

static final int NORM_PRIORITY:线程可以具有的默认优先级:5;

 

(5)toString()

Thread 类中的toString()返回该线程的字符串表示形式,包括线程名称,优先级和线程组(谁开启的你,就属于哪一个组)。

 

(6)yield

Static void yield();暂停当前正在执行的线程对象,并执行其他线程。被暂停的线程还是活的,还可以抢夺cpu执行权。

 

 

7、总结

什么时候用多线程?

当某些代码需要“同时”被执行时,就用单独的线程进行封装。你可以封装成三个类,也可以有更简单的写法。

class ThreadTest

{

public static void main(String[] args)

{

for(int x=0;x<100;x++)

{

System.out.println(

Thread.currentThread().getName()+”....”+x

);

}

for(int x=0;x<100;x++)

{

System.out.println(

Thread.currentThread().getName()+”....”+x

);

}

for(int x=0;x<100;x++)

{

System.out.println(

Thread.currentThread().getName()+”....”+x

);

}

}

}

利用多线程:

Class ThreadTest

{

Public static void main(String[] args)

{

New Thread()

{

Public void run()

{

for(int x=0;x<100;x++)

{

System.out.println(

Thread.currentThread().getName()+”....”+x

);

}

}

}.star();

for(int x=0;x<100;x++)

{

System.out.println(

Thread.currentThread().getName()+”....”+x

);

}

Runnble r=new Runnable()

{

public void run()

{

for(int x=0;x<100;x++)

{

System.out.println(

Thread.currentThread().getName()+”....”+x

);

}

}

};

new Thread(r).star();

}

}

 


2015-12-01 2015-12-05

R语言下载包报错?可能是IE浏览器在搞鬼!手把手教你修复(附CRAN镜像选择指南) 本文深入解析了R语言下载包时常见的网络报错问题,特别是Windows系统中因Internet Explorer代理设置导致的连接失败。文章提供了从重置IE配置、排查防火墙到优化CRAN镜像选择的完整解决方案,并附有详细的配置指南和自动化诊断脚本,帮助用户彻底解决R包安装难题。 阅读详情

相关推荐

JavaSE系列教程》

本专栏内容是为零基础正在学习Java的学习者量身定制的学习路线及方案,本教程字数超20w+,插图超过400+,知识体系极其全面,案例极其丰富。本配备有专门的学习群及学习视频,读者可加学习群与正在学习该阶段的人一同学习,有任何不懂的也可以观看于此教程配套的学习视频。

緑水長流*z 11万+

javajavaSEjavaEE的区别(适合新人)

这些文章看起来非常的脑残,甚至是无知,但是毫不谦虚的说,在我初学java的时候,甚至学了一年半载的时候,这两个东西我都不知道是什么东西。 所以这文章是为了让初学者更好的在大脑中构建这个编程的思想, 1,javaSE是什么? 怎么说吧,可以理解为javaSEjava的基石,如果将java程序想象成一座高楼大厦,那么javaSE就是地基。 官方的解释: Java SE(Java Platfor...

qq_41566219的博客 11万+

归结法证明真题分析

本文主要探讨了逻辑证明题的三种核心形式及其解题策略。第一类为A1∧A2∧A3→B的证明,常采用线性、单元、支持策略法等归结法,典型案例包括使用归纳法证明特定逻辑公式,并列举了历年真题。第二类为集合交集证明,典型案例为证明任意集合S和T的交集S∩T是S的子集,需将交集和包含关系用逻辑式表达。第三类为常规归结法证明,真题示例为使用归结法证明特定逻辑蕴含关系。掌握前两类证明方法后,第三类问题自然迎刃而解。

super_mochi1 254

javaSE学习笔记_目录

IO字节流 javaSE (二十九)IO.read()输出是int的原因、fileoutputstream的追加功能、用byte[]优化拷贝文件、Buffered缓冲区内存示意图 javaSE (三十)IO流异常处理、图片加密处理、输入文件路径并拷贝文件内容、在文件中键入内容 计算机基础知识 javaSE (一)数据类型转换、++/–运算符 javaSE (二)逻辑/位运算符、左移右移运算符、sw...

PizAn的博客 7031

JavaJavaSE学习笔记

本文包括Dos命令、基础概念、变量类型、类型转换、变量与常量、运算符、包、JavaDoc、输入输出、程序流程、数组、常用类以及面向对象编程(OOP)的基础知识。文章详细介绍了Java的运行机制、环境变量配置、变量命名规范、逻辑运算符、数组的声明与初始化、Arrays类的常用方法、时间类、字符串类、浮点数运算类、随机数类等。此外,还简要提及了面向对象编程的本质,即以类组织代码,以对象封装数据。这些内容为Java学习者提供了全面的基础知识和操作指南。

ayaishere_的博客 1000

JavaSE 总复习:语法到多线程全梳理

JavaSE 高效复习指南(150字摘要) 本文提出结构化复习JavaSE方法,强调从问题解决角度切入而非死记API。将JavaSE划分为12个核心模块,每个模块明确其解决的问题:基础语法构建代码基础,面向对象组织代码结构,集合管理数据,IO处理文件读写,多线程实现并发等。复习重点包括:掌握最小实现代码、识别常见错误、设计自测方案。特别提醒关注面向对象、集合、IO和多线程等核心模块,同时注意JDK版本差异。文章采用"问题导向+代码实践"的方式串联知识点,并提供详细笔记链接供深入查阅。 (150字)

一个普通29双非本的学习过程 4436

java学习笔记JavaSE基础

Java技术体系平台 JavaSE :标准版 面向桌面型应用(Windows下的应用程序)的Java平台。提供完整的Java核心API,也叫J2SE. JavaEE:企业版 开发企业环境下的应用程序。该技术体系中包含的技术 Servlet Jsp。主要针对Web应用程序开发。也叫J2EE. JavaME:小型版 支持Java程序运行在移动终端(手机、PDA:掌上电脑 条码扫描器、RFID读写器、P...

陌然白(小白)的博客 4048

JAVASE:多线程

1.什么是多线程?有了多线程,我们就可以让程序同时做多件事情2.多线程的作用?提高效率3.多线程的应用场景?只要你想让多个事情同时运行就需要用到多线程比如:软件中的耗时操作、所有的聊天软件、所有的服务器器。

跟着豪哥学Java 2388

区分java的三大版本:JavaSEJavaME、JavaEE

区分java的三大版本:JavaSEJavaME、JavaEE

2301_77899321的博客 1万+

Java学习笔记 - JavaSE

JavaSE全部知识点总结

CLXKZJ的博客 1117

javaSE学习笔记

JavSE笔记 编者的话 ​ 这个笔记是本人在重新学习javaSE后,大部分是在bilibili动力结点杜老师的视频上学习,本笔记中大量引用整合了其中的笔记,截图,代码等等非常感谢,感觉收获颇多,但是收获的知识点又太过分散,且担心忘记这些来之不易的精华,特做此总结,因为是个人笔记,难免会有一些这样那样的问题,如果读者发现错误或者影响到您正常的知识架构,望正在读此的您见谅! ​ ————————tyong–汤勇 文章目录JavSE笔记编者的话数组须知优点和

m0_49039508的博客 701

JavaSE-多线程

这里写自定义目录标题学习主题:JavaSE-多线程学习前言:线程实现:线程的状态: 多线程 学习主题:JavaSE-多线程 多线程的本质就是多条路径同时执行 学习前言: 1.一条路径 程序按顺序执行,线程安全,但是CPU利用率低 2.两条路径 即为多线程,可以并行执行,但是存在线程安全问题 3.进程 线程是操作系统的运行调度最小单位,是进程的运行单位 a:一个进程可以有多个线程 b:一个进程中的线程共享相同的内存单元 4.线程的优缺点 a:资源利用率高,程序响应快,程序设计存在便利 b:设计复杂(复

weixin_44158590的博客 461

JavaSE目录(尚硅谷学习笔记)

跳转到总目录 01、版本一:视频教程笔记 这个版本是我跟着视频教程做的笔记 教程来源:java基础到高级_零基础自学Java–尚硅谷–宋红康教程视频地址:https://www.bilibili.com/video/BV1ny4y1Y7CWMarkdown版笔记下载:h...

scy的技术博客 4249

Java初学者笔记--JavaSE

Java学习笔记 1 Java基础篇 待整理部分: 序号 内容 链接地址 1 Java概述 https://blog.csdn.net/weixin_44141495/article/details/107998818 2 Java环境搭建 https://blog.csdn.net/weixin_44141495/article/details/107998903 3 Java基础概念 https://blog.csdn.net/weixin_44141495/article/d

程序员小章的博客 1908

Java学习笔记JavaSE 多线程

多线程 文章目录多线程1、 基本概念 程序、进程、线程2、线程创建和使用(重点)2.1、Thread类2.2、Thread类中有关的基本方法2.3、线程调度 时间片式 抢占式等2.4、JDK5.0之前创建线程的两种方式2.41方式一:继承Thread类2.42方式二:实现Runnable接口2.43、比较创建线程的两种方式2.5、jDK5.0新增创建线程的两种方式2.51、方式一...

陌然白(小白)的博客 1154

JavaSE多线程笔记

javase多线程笔记

cc_1113的博客 911

JavaSE——多线程

首先要弄明白一点,不等于操作系统级别的线程Java创建线程Java虚拟机管理的,是。提供了统一的API,屏蔽了不同操作系统的差异性。操作系统级别的线程是由操作系统内核直接管理和调度的实体。它们是 CPU 调度的基本单位。现代 JVM 实现中,,即所谓的。ThreadC语言创建线程,才是真正意义上的操作系统上的线程。但是C语言在类Unix使用pThread来创建线程,但是在Windows使用的是Win32 API。所以。

weixin_69032308的博客 1068

JavaSE学习笔记

数组是一种容器,可以存储同类数据类型的多个值。数据类型 [] 数组名;方法是程序运行中最小的执行单元//定义public static 返回值类型 方法名(参数){方法体;return 返回值;//调用方法名();//调用//定义public class 类名{1、成员变量(代表属性,一般是名词)2、成员方法(代表行为,一般是动词)3、构造器4、代码块5、内部类// 获取类的对象类名 对象名 = new 类名();对象名.成员变量//访问属性。

m0_68356693的博客 817

JavaSEJava主要知识点目录整理

Java SE(Java Platform, Standard Edition)是Java编程语言的标准版,主要用于开发桌面应用程序、控制台应用程序以及一些简单的中小型Web应用。

wosixiaokeai的博客 1027

工具变量-上市公司企业耐心资本数据-含代码及原始数据(2008-2024年).txt

因文件较多,数据存放网盘,txt文件内包含下载链接及提取码,永久有效。失效会第一时间进行补充。样例数据及详细介绍参见文章:https://blog.csdn.net/T0620514/article/details/148623046

上一篇: JavaSE学习笔记_8:Java异常
下一篇: JavaSE学习笔记_11:Java-字符串类
java_程序媛
博客等级 码龄11年 26粉丝 24原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值