1) There is no practical difference as long as the LockPackageList object you choose for lock will not be disposed within the lifetime of the running code.
Actually in your second example, the common practice is to "lock with the resource you're trying to use", so in your case you had better do lock with ListPackageLabel itself.
2) No. You can see some .NET classes have provided .SyncRoot member for this purpose.
3) See (1).
4) The second code snippet is enough.
Just want to note that "lock" statement only provide protection for synchronized access if and only if all code within your application uses lock to access that resource. So if you experience "race condition" like errors for that resource, it would be useful to check whether all code that modifies the resource are protected by lock statement.