线程
package com.yudong.lesson01;
public class TestThread01 extends Thread{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("我在看代码:"+i);
}
}
public static void main(String[] args) {
TestThread01 testThread01 = new TestThread01();
testThread01.start();
for (int i = 0; i < 20; i++) {
System.out.println("我在写代码:"+i);
}
}
}
Runnable接口
//联系Thread,实现多线程同步下载图片
public class TestThread02 implements Runnable {
private String url;//网络图片的地址
private String name; //保存的文件名
public TestThread02(String url, String name) {
this.url = url;
this.name = name;
}
@Override
public void run() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(url,name);
System.out.println("下载了文件名为:"+name);
}
public static void main (String[] args){
TestThread02 t1 = new TestThread02("https://ss2.baidu.com/-vo3dSag_xI4khGko9WTAnF6hhy/baike/w%3D268/sign=6f44689c0cf431adbcd2443f7337ac0f/b58f8c5494eef01fe7da95cbe0fe9925bd317df6.jpg","懒洋洋.jpg");
TestThread02 t2 = new TestThread02("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F14315348362%2F1000.jpg&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1655948407&t=957c6f0139c53030e02782ed05469439","懒洋洋2.jpg");
TestThread02 t3 = new TestThread02("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F202004%2F24%2F20200424065313_QcdV5.thumb.400_0.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1655948545&t=9d5f6b542fe106884bc8c95e148ed2a5","懒洋洋3.jpg");
new Thread(t1).start();
new Thread(t2).start();
new Thread(t3).start();
}
}
//下载器
class WebDownloader{
//下载方法
public void downloader(String url,String name){
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常,downloader方法出现问题");
}
}
}
静态代理
public class StacticProxy {
public static void main(String[] args) {
new WeddingCompany(new You()).HappyMarry();
}
}
interface Marry{
void HappyMarry();
}
//真实角色
class You implements Marry{
@Override
public void HappyMarry() {
System.out.println("结婚,超开心");
}
}
//代理角色,帮助你结婚
class WeddingCompany implements Marry{
private Marry target;
public WeddingCompany(Marry target) {
this.target = target;
}
@Override
public void HappyMarry() {
before();
this.target.HappyMarry();//真实对象
after();
}
private void before() {
System.out.println("结婚之前,布置");
}
private void after() {
System.out.println("结婚之后,收尾款");
}
}
lambda表达式
interface ILove{
void love(int a,String b);
}
love = (a,b)->{ System.out.println("I like "+b+a); };
love.love(25,"鲁小姐");
线程状态
- 创建状态
- 阻塞状态
- 死亡状态
- 就绪状态
- 运行状态
- 建议线程正常停止,利用次数,不建议死循环
- 建议使用标志位
- 不要使用stop或者destroy等过时或者jdk不建议使用的方法
模拟网络延时:放大问题的发生性
线程礼让
- 让当前正在执行的线程暂停,但不阻塞
- 将线程从运行状态转变为就绪状态
- 让cpu重写调度,礼让不一定成功
守护线程
- 线程分为用户线程和守护线程
- 虚拟机必须确保用户线程执行完毕
- 虚拟机不用等待守护线程执行完毕
线程同步
- 一个线程持有锁会导致其他所有需要此锁的线程挂起
- 在多线程竞争下,加锁,释放锁会导致比较多的上下文切换和调度延时,引起性能问题
- 如果一个优先级高的线程等待一个优先级低的线程释放锁,会导致优先级倒置,引起性能问题
线程不安全例子
//不安全的买票
public class UnsafeBuyTicket {
public static void main(String[] args) {
BuyTicket buyTicket = new BuyTicket();
new Thread(buyTicket,"1").start();
new Thread(buyTicket,"2").start();
new Thread(buyTicket,"3").start();
}
}
class BuyTicket implements Runnable{
int ticketNums = 10;
boolean flag = true;//外部停止方法
@Override
public void run() {
while (flag){
buy();
}
}
private void buy(){
//判断是否有票
if (ticketNums<= 0){
flag = false;
return;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--);
}
}
产生死锁的四个必要条件
- 互斥条件:一个资源每次只能被一个进程使用
- 请求与保持条件:一个进程因请求资源而阻塞时,对已获取的资源保持不放
- 不剥夺条件:进程已经获得的资源, 在未使用完之前,不能强行剥夺
- 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系
生产者消费者模式
- 生产者:负责生产数据的模块
- 消费者:负责处理数据的模块
- 缓冲区:消费者不能之间使用生产者的数据,他们之间有个“缓冲区"
线程池
优点:
- 提高响应速度
- 降低资源消耗
- 便于线程管理
- corePpplSize:核心池的大小
- maximumPoolSize:最大线程数
- keepAliveTime:线程没有任务时最多保持多长时间后会终止
ExecutorService:真正的线程池接口
//测试线程池
public class TestPool {
public static void main(String[] args) {
//创建线程池
ExecutorService service = Executors.newFixedThreadPool(10);
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
//关闭连接
service.shutdown();
}
}
class MyThread implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
());
service.execute(new MyThread());
//关闭连接
service.shutdown();
}
}
class MyThread implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}