I have been developing applications based on C# (.net) and Java (J2EE) for the last 3 years.
But now I feel, Java, C# makes you lame (from learning point of view) and yo
Learn Forth. It has better Objects. And it is a virtual machine. Unless you want a real machine see Green Arrays or Sandpiper/John Rible for that.
Free threaded interpreted versions are all over the 'net. For practice. When you understand it write your own Direct Threaded version. Or see Forth Inc and buy one for your machine or use their free windows version.
Java is a Forth/C hybrid so if you want to go Java you will have some of the stuff under your belt.
Education:
Starting Forth - Brodie Thinking Forth - Brodie
The second is excellent for any language because it is the best book on factoring I know. Free Versions of both on the net.
If you want to do a hardware/FPGA Forth Stack Machines: The New Wave by Koopman
All the above books are free on the 'net.
Set up a performant C++ compiling environment such as Microsoft Visual C++ 2008 Express and go through all links in Bjarne Strousrup's The C++ Programming Language site, beginning with C++ Style and Technique FAQ. If you are experimented in any other language you don't need more :-)
If you want to understand the underlying concepts of programming languages, I would suggest a book such as John Mitchell's Concepts in Programming Languages. Follow this up by writing a few parsers/interpreters for simple languages. Another good resources is SICP, which is specific to Scheme (a LISP dialect), and available in full here. Once you've learned a few languages, it doesn't take too long to pick up the syntax and semantics of a new one (the core libraries on the other hand, can take quite a while to be familiarized with).
If you want to learn about how today's computers work, I'd recommend learning C and reading books such as Tanenbaum's Modern Operating Systems. C is useful in this context mostly for reading systems level code. Implementing a (very) simple operating system can be incredibly educational. However, something as simple as implementing a basic shell (like bourne shell, except simpler) is probably a better place to start. I'd also recommend learning about how networking works specifically, since it's such an integral part of modern computer systems.
I think you should start with C, but not as a necessary preamble for learning C++. Rather, for learning C. In other words, while you learn C put your efforts into learning the language, feeling the philosophy of the language and focusing on letting it sip into your skin. Be a good C programmer and you will be a good programmer, period. Not just a good C++ programmer -- this has nothing to do with learning C -- but a good programmer.
There's another reason for learning C first. It's easier than C++, much easier than C++, and it bridges well to C++ (in contrast to Java, which doesn't in all aspects but the most superficial object-oriented ones). I'm not talking about the syntax similarities: I'm talking about low-level programming. I'm talking about the concepts of pointers, which exist as themselves and in the form of iterators in C++. You can pass around functions in C, and you can pass around function objects in C++. C is fast to learn, and it will warm you up very effectively.
Learning C will also eliminate the fear of free functions some pure OO programmers tend to have. C++ is a hybrid language, and C truly is a subset of C++, not just by syntax but by philosophy as well.
Start by getting yourself the K&R book and drinking it through. You won't regret this.
In my opinion, you should learn C first in order to properly understand the base upon which C++ is built. Pick up a copy of "The C Programming Language" by Kernighan and Ritchie, widely considered the best reference on the language, and start reading through it. Once you fully understand C, you'll have the low-level base you need.
If you really want to know more about low level programming I would recommend learning C and Assembly. C++ is much more complex than C but really doesn't give you much more insight into low level concerns. It might be interesting if you want to learn about what type of concepts and constructs a programming language can be made up of though, since C++ has a lot of them.
There is also a lower level of your VM you don't seem to know yet and which you might want to explore. To learn about the internals of Java I would recommend learning how to program the JVM in (Java) Assembly language. Jasmin (http://jasmin.sourceforge.net/) is the reference assembler/syntax for this kind of programming. Another great resource is the Java Language specification (http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html) which contains a lot of Java internals. When you have learned C you can also use some lower level APIs the JVM provides (http://java.sun.com/javase/6/docs/technotes/guides/jvmti/) that allow you to retrieve low level information about a running JVM and write interesting things like debuggers.
If you learn this stuff and do some hacking on your own you will learn how the JVM works and what the compiler actually puts into your class files. It's also very likely that you discover some new things about the Java programming language itself you didn't know before even if you think you know everything about it.
You can also program the .Net VM in assembly by the way.