It's almost Christmas!
CS-Script - 306 bytes

var c=new string(' ',342).ToCharArray();var r=new Random();int e=18,i,j,w;for(;i&lt;e;i++){c[i*e+e]='\n';w=i&lt;5?i:i&lt;10?i-2:i&lt;16?i-6:2;for(j=1;j++&lt;w*2;)c[i*e+8-w+j]='#';}for(i=0;i&lt;10;){j=37+r.Next(288);if(c[j]=='#'&amp;c[j+1]&lt;42&amp;c[j-1]&lt;42&amp;c[j+e]&lt;42&amp;c[j-e]&lt;42)c[j]=i++&lt;5?'J':'O';}c[8]='^';c[27]='|';Console.Write(c);


Once more with formatting and comments:

// create 'char bitmap' filled with spaces
var c=new string(' ',342).ToCharArray(); 
// Random for placing ornaments
var r=new Random();
int e=18,i,j,w;
// once for each row
for(;i&lt;e;i++)
{
    // add new lines
    c[i*e+e]='\n';
    // determine width of tree for this row
    w=i&lt;5?i:i&lt;10?i-2:i&lt;16?i-6:2;
    for(j=1;j++&lt;w*2;)
        // add leaves
        c[i*e+8-w+j]='#';
}
for(i=0;i&lt;10;)
{
    // select random location
    j=37+r.Next(288); 
    if( // check we have a leaf
        c[j]=='#' &amp;
        // check surrounding to be leaf/space/new-line
        c[j+1]&lt;42 &amp; c[j-1]&lt;42 &amp; c[j+e]&lt;42 &amp; c[j-e]&lt;42)
        // add ornament if location is valid
        c[j]=i++&lt;5?'J':'O';
}
// light candle
c[8]='^';
c[27]='|';
// print
Console.Write(c);


It's basically C#, but using CS-Script allows me to skip all the boiler-plate.

Try it here!

Notes:

This currently outputs another line of white spaces below the tree to make sure the that 'checking for existing ornaments below' does not throw an IndexOutOfBoundsException. Other solutions would be:


Checking if it is the last line before checking below (adds a few more character)
Not adding ornaments to the 'stem' of the tree (Same byte count, but seems to me to be against rules)


I'll leave it to the OP if this should be changed.

Lastly, this is my first golf, so any feedback is appreciated. ;)