1.线程是CPU调度和执行的单位;
默认线程main【主线程,用户线程】和gc【垃圾回收线程,守护线程】两个;start()交替执行;run()相当于独自完成,与普通方法类似;线程开启不一定立即执行,需要CPU调度,耗费一定时间和资源;
2.FileUtils下载多张图片,需要先把阿帕奇下面的架包拷贝到lib【在src下】中。![在这里插入图片描述](https://img-blog.csdnimg.cn/20201017172224886.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzQ1NDQyMjYx,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201017172359518.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzQ1NDQyMjYx,size_16,color_FFFFFF,t_70#pic_center)
3.实现runnable方法,更充分利用了CPU资源,线程交替运行
静态代理;继承的方式改为实现接口方法
4.初始并发问题,多线程操作同一数据,引发数据紊乱。多线程共享数据引发数据安全问题![在这里插入图片描述](https://img-blog.csdnimg.cn/20201017172822643.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzQ1NDQyMjYx,size_16,color_FFFFFF,t_70#pic_center)
5。龟兔赛跑,
【兔子到90步时休眠2秒,或者每10步休眠十毫秒】
public void Race implements Runnable{
}
因为要达到终点,所以run()中i<=00在上面代码中模拟兔子中途休息run()中添加判断条件
6.实现callable接口【仅作扩充,公司不一定用的到】
先实现callable接口,并重写call方法;然后进行执行测试;
7.静态代理【中介角色代替实现真实角色功能】
真实对象【目标对象】代理对象都要实现共同 接口;代理对象要代替正式角色;类似的租房,房产中介,婚庆公司
8.lamda表达式、
匿名函数每次用,每次定义太麻烦
小括号内部是参数,花括号是输出语句
lambda演化过程:
接口的实现类调用lambda表达式-lik>静态内部类【实现类放在类的内部中,并加上static】 like2-> 局部内部类 like3 -> 匿名内部类 4 ->lambda表达式【去掉接口和方法】5->去掉参数的声明类型6-> 去掉小括号(仅有一个参数)和花括号(输出语句只有一行),两者之间用->连接7
接口的实现类调用lambda表达式,like调用方法;静态内部类【实现类放在类的内部中,并加上static】like2调用方法
局部内部类 like3调用方法
【把实现类放在主方法中,因为主方法是方法,内部不能定义方法,但是可以把内部方法放在一个类中,局部内部类可以在方法中出现】
匿名内部类 调用方法时没有名字4
lambda表达式【去掉接口和方法】5
去掉参数类型6
去掉小括号(仅有一个参数)和花括号(输出语句只有一行),两者之间用->连接7
9.函数式接口
10.隐式声明【类似的显示构造隐式构造】
在接口中,变量都是静态最终的常量,final static 修饰词可省略;方法都是公开抽象的,可省略;如果不写就是隐式声明;如果写了就是显示声明
11.线程状态
阻塞状态【wait ,sleep,同步锁定】
12.通过标识符停止线程
13.线程礼让
如果礼让句子注释掉变为普通方法,结束完一个方法另一个方法才执行
14.线程休眠【让客户给钱优化网络延时和模拟倒计时】
15.线程优先
16.线程优先级
线程优先级先进行设置,然后再调度start(),【只是概率线程优先级高的先运行,不绝对,概率比较大】线程优先级低的先运行叫线程的倒置;
17.显示锁和隐式锁;reentrantlock
package cn.kgc.tyl.test1017;
import java.util.concurrent.locks.ReentrantLock;
/**
* 同步锁 synchoronized :显示锁,锁开启关闭位置不显示;隐式锁
* reentranlock:可重入锁,开关位置显示;显示锁【不仅同步代码块,还可以同步方法】 一般用线程休眠来模拟扩大问题的发生概率可能性;
* 用可重入锁来取代sychoronized 同步代码块,执行效率更高;
*/
public class ShowSynchronizedLock implements Runnable {
private int num;// 第几张票;
private int count=10;// 总票数;
private final ReentrantLock LOCK = new ReentrantLock();// 常量可重入锁;
@Override
public void run() {
while (true) {
LOCK.lock();// 加锁,给同步代码块给容加锁
try {
if (count <= 0) {
return;
}
Thread.sleep(200);
count--;
num++;
System.out.println(Thread.currentThread().getName() + "--买了第" + num + "张票,还剩" + count + "张");
} catch (Exception e) {
e.printStackTrace();
} finally {
LOCK.unlock();// 解锁
}
}
}
}
************************************************************************************************************************************1-1
package cn.kgc.tyl.test1017;
/**
*
* 测试同步锁
*/
public class TestShowSynchronizedLock {
public static void main(String[] args) {
ShowSynchronizedLock buyTicket = new ShowSynchronizedLock();// 共享数据,建立一个对象;
Thread person1 = new Thread(buyTicket, "唐哥");
Thread person2 = new Thread(buyTicket, "远哥");
Thread person3 = new Thread(buyTicket, "黄牛哥");
person1.start();
person2.start();
person3.start();
}
}
*****************************************************************************************************************************************1-2
package cn.kgc.tyl.test1017;
/**
*
* 创建两个线程、进行抢票功能
* 用while(ture)做循环判断时,就不用for循环了
*
*/
public class UnShowSynchronizedLock implements Runnable {
private int count=10;//总票数
private int num=0;//剩余票数
@Override
public void run() {
while (true ) {
synchronized (this) {
if (count<=0) {
return;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
count--;
num++;
System.out.println(Thread.currentThread().getName()+"买了第"+count+"张票,还剩"+num+"张 票");
}
}
}
}
**********************************************************************************************************************************2-1
package cn.kgc.tyl.test1017;
public class TestUnShowSynchronizedLock {
public static void main(String[] args) {
UnShowSynchronizedLock buyTicket = new UnShowSynchronizedLock();
Thread person1 = new Thread(buyTicket, "唐哥");
Thread person2 = new Thread(buyTicket, "远哥");
Thread person3 = new Thread(buyTicket, "黄牛哥");
person1.start();
person2.start();
person3.start();
}
}
***************************************************************************************************************************************2-2
17.守护线程
线程分为守护线程和用户线程;系统默认的用户线程是主线程;
虚拟机中监控内存,垃圾回收等待,日志管理等都属于守护线程,一般默认不显示在控制台,默认false,虚拟机不用等待守护线程执行完毕;
MainThread主线程,以及start()启动的自定义线程都是用户线程,虚拟机必须确保用户线程执行完毕之后,守护线程不一定立即结束;
`
package cn.kgc.tyl.test1017;
public class God implements Runnable{
@Override
public void run() {
while (true) {
System.out.println("阿门!");
}
}
}
****************************************************2
package cn.kgc.tyl.test1017;
public class You implements Runnable {
@Override
public void run() {
for (int i = 0; i <=20; i++) {
System.out.println(Thread.currentThread().getName()+"你活了"+i+"0岁,god must be bless me");
}
System.out.println("极乐世界, comming");
}
}
****************************************************3
package cn.kgc.tyl.test1017;
public class TestDaemon {
public static void main(String[] args) {
You you=new You();
God god=new God();
Thread t1=new Thread(god);
Thread t2=new Thread(you);
//设置守护线程
t1.setDaemon(true);//设置为true,则为守护线程,默认false,非守护线程
//开始运行
t1.start();
t2.start();
}
}
18线程同步机制
【线程倒置,线程优先级低的先运行,其本身执行时间相对较短,执行效果更明显;】【同步锁使用会降低性能,不建议加过多的锁 。只有修改的的地方才需要修改,只读的部分不需要修改,浪费资源】【wait()不释放锁,sleep()释放锁】
线程都会来来额外的开销,如中央处理器调度时间,【并发控制开销】;每个线程在【自己的工作内存】交互,内存控制不当会造成数据不一致;
队列加锁才可以保证线程同步;
模拟银行取钱,买票,Arrylist【同一时间添加数据在相同位置,个数少于循环次数】,非安全线程
19死锁【多个线程共享资源某一个同步代码块拥有超过一把以上的锁,导致多个线程都在等大对方释放资源都停止的情形】
package cn.kgc.tyl.test1017.deadlock;
import java.awt.Choice;
/**
*
* 死锁,多个线程相互抱着对方所要的资源
*/
public class DeadLock {
public static void main(String[] args) {
Thread t1=new Thread(new Makeup(0, "白雪公主"));
Thread t2= new Thread(new Makeup(1, "女巫"));
t1.start();
t2.start();
}
}
/**
* 共享资源1.口红类
*
*/
class Lipstick {
};
/**
*
* 共享资源2.镜子类
*/
class Mirror {
};
/**
*
* 化妆
*/
class Makeup implements Runnable {
static Lipstick lipstick = new Lipstick();// 保证资源唯一,静态
static Mirror mirror = new Mirror();
int choice;//选择
String girlname;//使用化妆品的人;
public Makeup(int choice, String girlname) {
super();
this.choice = choice;
this.girlname = girlname;
}
@Override
public void run() {
//化妆
try {
makeup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//化妆的方法
private void makeup() throws InterruptedException {
if (choice==0) {
synchronized (lipstick) {
System.out.println(this.girlname+"获得口红");
Thread.sleep(1000);
}
synchronized (mirror) {//下一秒想获得镜子
System.out.println(this.girlname+"获得镜子");
}
}else {
synchronized (mirror) {
System.out.println(this.girlname+"获得镜子");
Thread.sleep(2000);
synchronized (lipstick) {//一秒后想获得口红
System.out.println(this.girlname+"获得口红");
}
}
}
}
}
/**
*
白雪公主获得口红
女巫获得镜子
女巫获得口红
白雪公主获得镜子
* */
20.信号灯方法【取反,消费者生产者模式】【管程法,并发协作模型】
21使用线程池
callable接口有返回值,所以输出参数100;