Executing dbms_job.run runs the job in your current session. So if this is "hanging" it suggests that the procedure is taking a long time to run.
Call the procedure directly and trace its execution when you have 40k+ ids. This should give you some insight to what's happening.
Also - by calling the run command in the same session you're not running these in parallel. You're calling them serially!
For example, this submits two jobs which run for 10 seconds. The whole process takes 20 seconds to run, with the second job starting 10s after the first:
SQL> declare
2 v_log_flag varchar2 ( 1 ) := 'Y';
3 vjob1 number := 1;
4 vjob2 number := 2;
5 begin
6 dbms_job.submit ( job => vjob1, what => '
7 begin dbms_output.put_line(to_char(sysdate, ''hh24:mi:ss'')); dbms_lock.sleep(10); end;', next_date => null ) ;
8 dbms_output.put_line ( ' Job1: ' || to_char ( vjob1 ) ) ;
9 dbms_job.submit ( job => vjob2, what => '
10 begin dbms_output.put_line(to_char(sysdate, ''hh24:mi:ss'')); dbms_lock.sleep(10); end;', next_date => null ) ;
11 dbms_output.put_line ( ' Job2: ' || to_char ( vjob2 ) ) ;
12
13 dbms_job.run ( vjob1,false ) ;
14 dbms_job.run ( vjob2,false ) ;
15 end;
16 /
Job1: 17
Job2: 18
02:28:19
02:28:29
PL/SQL procedure successfully completed.
Elapsed: 00:00:20.44
There's no need to call run. Just commit and let them run in the background. You'll then get the parallel execution you want.