线程

线程
1.什么是线程:
1.进程:就是某一个应用程序在计算机中运行时计算机为该应用程序所分配的资源;在多任务计算机中,一个计算机可以运行多个程序;
2.线程:线程是进程中使用计算机为进程所分配的计算机资源进行数据计算的基本单位;一个进程中至少要包含一个进程。
3.多线程,当一个进程中有多个线程执行,这个现象叫多线程;
4.Java中的线程体系: 1.Thread类该类用于表示对线程的描述;
2.实现Runable接口:实现了该接口的类并不是线程类,只是表示具有可运行性,能够被其他线程对象调用执行;
2.自定义线程和创建执行线程:
1.继承Thread类:
继承该类之后重写run();方法,将自定义的线程需要执行的代码写在run方法中;该线程启动后就会去执行run方法中的代码;
public void run(){
}

调用start方法启动线程;
Java程序在执行的时候,jvm进程会启动一个线程来执行该程序的主方法;此线程称为主线程【线程名字就叫“main”】;只有主线程在执行main方法的时候才能执行到main方法中定义的创建和启动其他线程代码;如果启动了多个线程,则这些线程的名字按照线程启动顺序从thread-0到thread-N;
在Thread中的getName();方法可以获得线程的名称;如果线程代码中没有run方法,在不知道当前线程对象时,可以使用Thread类中currentThread();方法来获取正在执行的线程的名称;
	Thread a=Thread.curreatThread();
	String b=a.getName();
2.实现Runable接口(该接口中只有一个run方法):
	自定义实现类实现该接口重写该接口的run方法;
	此时实现类并不是线程类,只是表示该类的对象可以作为线程对象的执行目标来实行;
3.实现Callable接口;该接口中有一个方法call;该方法具有返回值;如果线程在执行过程中调用了一个具有返回值的方法,则可以使用该接口去创建线程;

class ThreadTest2 implements Runnable(){
public void run(){
String a=Thread.currentThread.getName();
for(int i=0;i<10;i++){
sout(a+"—"+i);
}
}
}
psvm(){
ThreadTest2 k=new ThreadTest2();
Thread t=new Thread(k,“线程新名字”);
}

并发:多个线程同时发生;
并行:多个进程同时执行;
Java中每个线程都有优先级;优先级高的被cpu调度的概率高于低优先级的线程;设置线程的优先级并不能让cpu立即去执行线程,而是让cou有更多机会去调用高优先级线程;线程的优先级分十个等级;用1到10表示;10优先级最高;5是每个Java线程默认的优先级;
1.Thread类中的方法:
	1.static Thread currentThread();//获取此代码所在的方法正在执行的线程对象;
	2.static void sleep(long millis);//让执行此代码所在的线程暂时停止;等到参数所表示的时间结束之后可以继续执行;
	3.interrupt();停止; 
2.Object类中的方法:
	1.void notify();//唤醒某个线程;
	2.void notifyAll();//唤醒所有等待的线程;
	3.void wait();//在某个方法中调用此方法;则会让执行该线程的方法强制等待;,通过1.2的方法唤醒该线程之后才会接受cpu的调度;
	4.void wait(long millis);//如果此代码所在的线程被唤醒,或者参数所表示的时间结束,则该线程可以继接受cpu的调度来执行,否则一直处于暂停;
	5.static void yield();让出cpu时间片;

3.线程的状态【生命周期】:
1.新建:创建线程类的对象;
2.就绪/可运行:新创建的线程对象调用start方法后,线程就处于此状态(等待接受cpu调度执行);
3.运行中:cpu正在调度的线程就处于此状态;
4.阻塞:暂时停止执行的线程;处于此状态的线程在阻塞状态结束之前不会接受cpu的调度;阻塞状态结束后才会处于就绪状态接受cpu的调度;
5.死亡/消亡:当线程之中的所有内容全部执行完毕时,该线程就处于此状态;当某个进程中还有在执行状态的线程时,则该进程就不会结束。即使主线程已经结束
注意:线程在创建之后进入运行就绪状态只能调用一次start方法,如果对一个线程多次调用start方法,就会出现IllegalThreadStateException;非法线程状态异常;如果对已经消亡的状态也会出现IllegalThreadStateException;异常;
4.并发访问和同步线程:
1.线程安全是指在多线程程序运行的环境中,多个线程共同使用【共享】同一个资源【数据】就有可能导致该资源【数据】计算错误的现象;
2.同步和异步:异步是指多个线程同时执行,每个线程之间不相干;同步指的是在执行到某一段代码时,必须由某个线程先执行完该代码才能由另外一个线程执行该代码;
3.解决线程安全问题的方式:线程同步机制【锁机制】:将多个线程执行时所共享的数据【资源】放在synchronized代码块中;
synchronized(锁对象){
//需要同步执行的代码
//具有对共享数据进行计算的代码
}
监视器对象【锁对象】:可以是Java语言中的任意一个类的对象,它是作为线程执行该代码块中代码‘标志’,只有当线程拥有此标志时,该线程才能执行同步代码块中的代码;否则就在执行完同步代码块之前的代码进行等待;当拥有此标记的代码块执行完该代码时就会释放该锁,其它线程就会抢夺该锁来执行代码块中的代码;
4.多个线程要同步执行同步代码块中的代码,则这些线程拿到的必须是一个锁对象;

单例模式:懒汉式存在线程安全问题。
5.同步方法:如果某个方法中的所有代码都在同步代码块中,则此方法可以定义为同步方法;
1.语法:public static synchronized void show(){
}
2.同步方法中的锁对象:
静态同步方法的锁对象是该方法所处的类的镜像;
非静态同步方法的锁对象是this;【当前类的某一个对象】
注意:根据需求,尽量不要将一个方法中的所有代码都放在同步代码块中,除非需求需要;
并不是某个方法中的所有代码都处于同步代码块中时就可以将该方法定义为同步方法;
在自定义功能的时候最好对该功能提供两种形式,一是线程不安全的提高效率,二是线程安全的,保证数据安全;

5.线程的等待唤醒机制【线程间的通信】:
需求:有一个出版社,该出版社有两个功能,印刷书籍,出售书籍,定义两个线程,印刷一本书,出售一本书,如果没有书则需要先印刷再出售;
异常:非法监视器异常;出现该异常主要是由于没有在同步代码中执行wait方法;这些方法属于Object类,但不是任何对象就能调用,这些方法只能由同步锁对象调用;

6.死锁和线程优先级:
1.生产者消费者可能会出现死锁;
2.锁嵌套锁,就会死锁;同步代码块中包含同步代码块,锁对象不一样就可能发生死锁;
3.java线程中可以设置优先级,但是在没有使用wait();notify();notifyAll();的代码中设置的线程的优先级的作用很小;在线程等待唤醒机制中设置了优先级,有一点作用;

public class Deadlock{
psvm{
new DeadlockThread1().start();
new DeadlockThread2 ().start();
}
}
enum Lock{
A.B
}
class DeadlockThread1 implements Thread{

public void run(){

while(true){
synchronized(Lock.A){sout()}
synchronized(Lock.B){sout()}

}

}

}
class DeadlockThread2 implements Thread{

public void run(){

while(true){
synchronized(Lock.B){sout()}
synchronized(Lock.A){sout()}

}

}

}
练习:火车站售票;总共100张票,多个售票窗口;同时售票,当所有的车票都卖完就不能再售票;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值