Java基础学习总结----进程与线程

知识点一:进程,线程与多线程

Windows系统号称多任务(可以同时运行多个应用程序)。

宏观上看: windows确实是允许了多个程序。

微观上看:cpu快速切换执行任务,由于速度特别快,我们人感觉不到这个切换的过程。

1.进程:就是正在运行的程序,分配内存让应用程序能够运行。

2.线程:线程在一个进程中负责代码的执行, 就是一个进程中的执行路径。

3.思考

A.没有学习线程,为什么代码可以执行?

java程序在运行的时候,jvm会帮我们创建一个主线程来执行代码。主线程主要负责main方法中的代码执行。

B.一个java程序中至少有2个线程

一个是主线程只要负责main方法中的代码执行,一个垃圾回收器线程,负责垃圾回收。

4.多线程 :在一个进程中多个线程同时执行不同的任务。

"同时":单核CPU快速切换多个线程执行任务,速度特别快,我们人感觉不到切换。

4.1多线程的好处:

a.解决一个进程中同时执行多个任务的问题。

b.提高资源的利用率。

4.2多线程的弊端:

a.增加CPU的负担。不线程越多越好。

b.降低了一个进程中线程的执行概率。

c.容易引发线程安全问题。

d.出现死锁现象。

知识点二:创建线程的两种方式

方式一:Thread (线程类)

1.需要定义一个类来继承Thread类

2.重写thread类中run方法,把自定义线程的任务代码写在run方法中。每一个线程都有自己的任务代码 ,jvm创建的主线程的任务代码就是main方法,自定义的线程的任务代码就写下run方法中,自定义的线程就需要来执行run方法中的代码

3.创建Thread的子类,并且调用start方法开启线程

注意点:

一旦线程开启了,会默认执行线程对象中的run方法, 但是千万不要自己直接调用run方法,如果直接调用了run方法就和普通方法没有区别

class MyThread extends Thread {

@Override

public void run() { //多线程执行任务的地方

//自定义线程的任务代码

for(int i = 0;i<100;i++){

System.out.println("多线程:"+i);

}

}

}

public class Demo1 {


public static void main(String[] args) { //从上到下依次执行。

// TODO Auto-generated method stub

//创建一个自定义线程对象

MyThread t = new MyThread();

//开启线程来执行任务

t.start();

//main方法中的代码是在主线程中执行的

for(int i = 0;i<100;i++){

System.out.println("主线程:"+i);

}

}

}

线程中常用的方法:

Thread(String name)初始化线程的名字

getName()返回线程的名字

setName(String name)设置线程对象名

sleep()线程睡眠指定的毫秒数。

getPriority()返回当前线程对象的优先级   默认线程的优先级是5

setPriority(int newPriority)设置线程的优先级    虽然设置了线程的优先级,但是具体的实现取决于底层的操作系统的实现 (最大的优先级是10,最小的1, 默认是5)。

currentThread()返回CPU正在执行的线程的对象

public class Demo3 extends Thread{

//定义一个构造方法来调用父类的构造方法。

public Demo3 (String name){

super(name);

}

//重写run方法

@Override

public void run() {

// TODO Auto-generated method stub

for(int i = 0;i<50;i++){

//设置线程睡眠0.5秒    单位是毫秒

//异常只能处理  :thread父类中run方法没有抛出异常,所以子类也不允许抛出异常。

/*try {

//Thread.sleep(500); //谁执行我sleep代码就睡眠谁   睡眠的是自定义线程

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}*/

//getName();获取当前执行run方法线程的名字。

System.out.println(this.getName()+":"+i);

//获取自定义线程对象

//Thread.currentThread()指的是执行run方法的对象。// d对象在执行run方法

System.out.println("当前线程对象"+Thread.currentThread());

System.out.println("this对象:"+this);

}

}

public static void main(String[] args) throws InterruptedException {

// TODO Auto-generated method stub

//创建线程时给他指定名字

Demo3 d = new Demo3("张三");

//设置名字

d.setName("老王");

//开启线程

d.start();

//Thread.sleep(500); //主线程在执行 , 睡眠的是主线程。

System.out.println("d============"+d);

//获取当前线程对象(主线程)

Thread  maintT = Thread.currentThread();

System.out.println("当前线程对象:"+Thread.currentThread());

System.out.println("获取主线程的优先级:"+maintT.getPriority());

}

}

java给线程加锁 :

锁对象可以是任意一个java中的对象

java中的任意一个对象 都会有一个对象的状态 ,就可以通过对象的状态来作为锁的一个标识符。

statue = 0表示锁是关闭statue = 1表示锁打开。

synchronized (锁对象) {

}

同步代码块的使用注意点:

1.任意一个对象都可以做锁对象

2.如果你在同步代码块中调用了sleep方法 ,不会释放锁对象

3.只有真正存在线程安全的时候才需要使用同步代码块,否则会降低执行效率

4.多线程操作锁对象必须是唯一的 ,否则无效

思考:出现线程安全的问题根本原因:

1.存在两个或两个以上的线程。并且线程之间共享着一个资源。

2.多个语句操作了共享资源

知识点三:线程的通讯

线程的通讯:一个线程完成自己的任务,去通知另外一个线程去完成另外一个任务。

wait();等待    如果线程执行了wait方法 ,那么该线程就会处于一个等待状态,等待状态的线程必须要通过其他线程来调用

notify()方法来唤醒。

notify();唤醒   随机唤醒线程池中的一个线程。

notifyAll();唤醒所有等待的线程

生产者和消费者。

wait和notify的使用注意点 :

1.wait方法和notify方法是属性Object对象

2.wait方法和notify方法必须在同步线程中执行

3.wait方法和notify方法必须有锁对象来调用

你可能感兴趣的:(Java基础学习总结----进程与线程)