Although I found it easier with my first, my second (DD) was a complete nightmare like this.
Of course they don't have a sense of danger.
Tips. Don't be constantly saying "stop, stop stop, careful don't run into the road" or they stop listening. Practise somewhere. Try letting him run off somewhere (safe) and then yell "STOP" at the top of your voice, and see if it works. Then you can use the STOOOOOOP moment when you really need it.
Be consistent. It's an old addage, but one which works. Took a LONG time, but did kick in with both DDs. Always take the buggy and you can use it as a threat. Ask him to hold the buggy as you are walking along the road, in a carpark etc. But go places where you can let him run a bit as well. When he does come back praise massively.
Frankly, if he is becoming dangerous, then strap him in the buggy, and tell him you are doing so because he wouldn't walk nicely. They pick up on this stuff quickly.
I will let my DD2 (2.5) walk along where it is safe, but I ALWAYS require her to hold my hand when walking through carparks etc. If she refuses, drops, hangs, tantrums... I just stand still and say "we are not going anywhere until you hold my hand, or I will (put you in buggy, pick you up etc). Again - if they are yearning for independence to walk - they will pick this up quickly enough.
It seems like the longest time, but you will get there in the end if you are consistent.