Enable and disable component repeatedly under condition

i wanted to make a flash effect if my hunger reaches the number 20. I wanted to enable my outline and than disable it after 2 sec. and than enable it again and do this whole thing again until my hunger is more than 20 but my script starts spaming my Debug.Log and is turning my outline on and off and is not waiting the 2 sec. why?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System;

public class AEffects : MonoBehaviour
{
    private PlayerMovement playerMovement;
    private Outline outline;
    // Start is called before the first frame update
    void Start()
    {
        outline = GetComponent<Outline>();

        playerMovement = FindObjectOfType<PlayerMovement>();
    }

    // Update is called once per frame
    void Update()
    {
        

        if (playerMovement.hunger <= 20)
        {
            outline.enabled = true;
            StartCoroutine(Blincking());
        }
        if(playerMovement.hunger >= 20)
        {
            outline.enabled = false;
        }
    }

    IEnumerator Blincking()
    {
        outline.enabled = true;
        yield return new WaitForSeconds(2);
        Debug.Log("Time is up");
        outline.enabled = false;
        yield return new WaitForSeconds(2);

    }
}

Since Update runs every frame, you are starting a new coroutine every frame as long as the hunger is less than 20. You need to check the coroutine is not already running. You also need to make your coroutine loop (FOLLOWING CODE NOT TESTED)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System;

public class AEffects : MonoBehaviour
{
    private PlayerMovement playerMovement;
    private Outline outline;
    private bool outlineBlinking;
    
    // Start is called before the first frame update
    void Start()
    {
        outline = GetComponent<Outline>();

        playerMovement = FindObjectOfType<PlayerMovement>();
    }

    // Update is called once per frame
    void Update()
    {
        if (playerMovement.hunger < 20 && outlineBlinking == false)
        {
            outlineBlinking = true;
            StartCoroutine(Blinking());
        }
        else if(playerMovement.hunger >= 20 && outlineBlinking == true)
        {
            StopAllCoroutines();
            outlineBlinking = false;
            outline.enabled = false;
        }
    }

    IEnumerator Blinking()
    {
        WaitForSeconds wait = new WaitForSeconds(2);
        while(true)
        {
            outline.enabled = true;
            yield return wait;
            outline.enabled = false;
            yield return wait;
        }
    }
}

However, coroutines are not needed in your case since you already use Update. You just need a little bit of logic to handle the waits (CODE NOT TESTED)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System;

public class AEffects : MonoBehaviour
{
    private PlayerMovement playerMovement;
    private Outline outline;
    private float timer;
    
    // Start is called before the first frame update
    void Start()
    {
        outline = GetComponent<Outline>();

        playerMovement = FindObjectOfType<PlayerMovement>();
    }

    // Update is called once per frame
    void Update()
    {
        if (playerMovement.hunger < 20)
        {
            timer += Time.deltaTime;
            outline.enabled = Mathf.Repeat(timer, 4) < 2f;
        }
        else
        {
            outline.enabled = false;
            timer = 0;
        }
    }
}