【线程二】【翻译】什么是线程?

引言

不论在哪个领域,多线程避免不了。

线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速。比如,如果一个线程完成一个任务要100毫秒,那么用十个线程完成改任务只需10毫秒。Java在语言层面对多线程提供了卓越的支持,它也是一个很好的卖点。

 

java.lang.Thread class but JVM plays an important role of all Thread activities. Thread is used to execute task in parallel and this task is coded inside run() method of Runnable interface. You can create Thread in Java programming language by either extending Thread class , implementing Runnable or by using Executor framework in Java. RememberRunnable doesn’t represent Thread actually its a task which is executed by Thread. Read more about extends Thread vs implements Runnable here.

创建线程两种方式,Runnable不代表线程,只代表一个被Thread执行的任务。

1. Thread in Java represent an independent path of execution. (classic definition but I still like it). Thread is represented by

Thread代表独立执行路径

2. During its life time thread remains on various Thread states like NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING which describe what thread is doing. NEW means thread is just created but not yet stated, RUNNABLE means thread is started but waiting for CPU to be assigned by thread scheduler. BLOCKED, WAITING and TIMED_WAITING means thread is not doing anything instead its been blocked and waiting for IO to finished, class or object lock, or any other thread etc.

线程状态代表的意义:新建(无状态),可运行(需要cpu分配线程执行调度),阻塞,等待,timed等待;(后三个stated代表不做任何事,只是等待IO完成,类锁,或等其它线程)

3. There are two kinds of Thread in Java daemon or non daemon (also called user threads). Java programs runs until there is at least one non-daemon thread exists. First non-daemon thread started by JVM is main thread which is created by JVM and responsible for executing code inside main method in Java. This is called “VM thread” in HotSpot Virtual Machine. Any thread created using java.lang.Thread start() methods from main thread is by default non-daemon but you can make it daemon by calling setDaemon(true) method. Newly created thread in Java inherits daemon property from the thread which creates it. Since main thread is non-daemon, any thread created by it by default remains non-daemon.

Java中两种线程(守护线程、非守护or用户线程)。

本来默认线程都是非守护线程,由jvm发起(在HotSpot Virtual Machine里,是java虚拟机的一种),叫vm线程。他们都是由java.lang.Thread start() 方法在主线程里面发起的,如果你想搞守护线程,使用setDaemon(true)方法。然后在里面再起线程,都有了守护属性。

因为主线程非守护的,在其里面搞任何线程默认都是非守护。

【总结】线程守护属性是遗传的。看他爹。

4. Every Java threads has priority and name. You can set priority and assign meaningful name while creating object of java.lang.Thread class in Java. its recommend practice to give every thread a meaningful name while creating it , it helps later when you debug your Java program or take thread dump for analysis. Otherwise Java will give your Thread default name like “Thread-number” if Thread is created using java.lang.Thread or “pool-number-thread-number” if Thread is created using ThreadFactory. In Java higher priority thread get preference in Execution over lower priority thread. you can check priority by using method like getProiroty() from thread class.

每个线程有名有优先级。建议创建线程时候给起名。否则默认名字是Thread-数字。优先级高先运行。可以通过getProiroty()方法看优先级。

5.Creation of thread is a time-consuming job so having a Thread pool for performing task concurrently is modern day requirement of performance and scalability. Java 5 provides Executor framework which encapsulate task of creating and managing thread from application code. Consider using Thread pool if your application requires to handle load. In web and application server manages this thread pool because each request is processed in its own thread.

【建议使用线程池】每个线程创建是耗时的,所以,如果应用需要处理负载,建议采用java5提供的Executor框架创建线程池。在web或者app里,server管理线程池。因为每个请求都相当于是处理线程。

6. Thread.sleep() method is used to pause thread for specified duration. It is an overloaded method defined in java.lang.Thread class. On the other hand Thread.join() is used to wait for another thread to complete its task before running and yield() method is used to relinquish CPU so that other thread can acquire it. See difference between sleep, wait and yield for details.

sleep方法用于停止当前线程。join用于等待其它线程完成才运行自己的。yield方法用于放开cpu让其它线程进来。

关于两者区别,请看引文链接

7. wait() and notify() methods are used to communicate between two threads i.e. for inter thread communication in Java. Always check condition of  wait() method in loop and call them from synchronized context. wait() is a method which is defined in object class, and puts the current thread on hold and also releases the monitor (lock) held by this thread,  while notify() and notifyAll() methods notifies all thread waiting on that monitor. There is no guarantee which thread will picked up by thread scheduler and given CPU to execute because of of notification. To learn more about how to use wait, notify and notifyAll method to achieve inter-thread communication, see my post about solvingproducer consumer problem in Java using wait and notify method.

wait 和notify方法用于两线程通信,对于Java中的通信情况,总是检查在循环中wait方法的条件(Yol注:一般是while (true)循环),然后再加以同步的情况下调用它。wait()是在对象类中定义的方法,能把当前线程挂起,且释放该线程锁(不占用锁,sleep相反)。

notify() and notifyAll() 方法通知所有wait()的线程,但哪个线程先由CPU优先调度,并不知道。要了解更多wait(),和notifyAll的实现线程间的通信,请点击引言链接,参阅有关solvingproducer消费问题,《在Java中使用wait和notify方法》

8. Thread scheduling is done by Thread Scheduler which is platform dependent and stays inside JVM. There is no known way to control thread scheduler from Java and many of thread related decision is done by scheduler like if there are many threads is waiting then which thread will be awarded CPU.

线程调度是由线程调度器依赖JVM。Java中无法控制调度器线中程调度来控制从Java线程调度和多线程相关的决定是由调度器完成的一样,如果有多个线程在等待随后的线程将被授予CPU。

9. Thread.isActive() method is used to check whether a thread is active or not. A thread is said to be active until it has not finished either by returning from run() method normally or due to any exception. Thread.holdsLock() method is used to check if a thread holds a lock or not. See how to check if thread holds lock or not for more details.

方法Thread.isActive()用于检测一个线程是否为Active. 线程是Active,表明此线程在run方法里面正常未执行完,或因为异常没执行完。

方法Thread.holdsLock()用于检测一个线程是否拥有锁,想看更多搜索《how to check if thread holds lock or not》

10. Every thread in Java has its own stack, which is used to store local variables and method calls. Size of this stack can be controlled using -XX:ThreadStackSize JVM option e.g. -XX:ThreadStackSize=512.

每个java线程有自己的栈,用于存本地变量和方法调用。栈大小这样控制:

-XX:ThreadStackSize=512.

 

11. Java 5 introduced another way to define task for threads in Java by using Callable interface. It’s similar to Runnable interface but provides some more capability e.g. it can return result of task execution, which was not possible in Runnable, because return type of run() method was void. Like its predecessor it define a call() method which can returnFuture<T> object, you can call get() method on this object to get the result of task execution. To learn more about Callable, please see difference between Runnable and Callable interface in Java.

Java5中介绍了另一个实现线程的方法,是调用Callable接口,但和Runnable接口不同的是,它可以return内容!欲知详情,点击引文链接。

12. Java provides interrupt() method to interrupt a thread in Java. You can interrupt a running thread, waiting thread or sleep thread. This is the control Java provides to prevent a blocked or hanged thread. Once you interrupt a thread, it will also throw InterruptedException, which is a checked exception to ensure that your code should take handle interrupts

Java提供了interrupt()方法打断线程(running,waiting,sleep状态的线程)

13. Java provides two ways to achieve mutual exclusion in your code, either by using synchronized keyword or by using java.util.concurrent.lock implementations. Former is more popular and oldest way to achieve mutual exclusive code but  Lock interface is more powerful and provides fine grained control and only available from Java 5, Tiger. You can use synchronized keyword to either make an entire method mutual exclusive or only critical section by declaring a synchronized block. Any thread needs to hold monitor or lock, required by that critical section in order to enter into synchronized block or method, they release that lock, once they exit, either normally or abruptly due to any error.

Acquisition and release of monitor is done by Java itself, so its safe and easy for Java programmer, on the other hand if you decide to use Lock interface, you need to explicitly acquire lock and release it, this requires more caution. Popular idiom is to release the lock in finally block. See my posthow to use ReentrantLock in Java for code example and few more details.

Java提供了两种方式能在你的代码实现互斥,通过使用synchronized关键字,或使用java.util.concurrent.lock实现

前者是更受欢迎,实现互斥代码最古老的方式,但lock更强大,提供细粒度的控制。可以使用synchronized关键字声明一个synchronized块使整个方法互斥或仅临界区。任何线程需要持有监视器或锁定,才能进入synchronized块或方法所要求的关键部分,一旦退出,无论是正常还是突然因任何错误,锁就释放了。

获得或释放monitor是由Java本身完成的,对Java程序员来说它是安全和方便(控制的);

另一方面,在你决定使用锁接口。你需要明确的获取锁和释放,多谨慎。流行的做法是在finally块释放锁。细节看引文。

14. One more thing to know about Thread in Java is that its not started when you create object of Thread class e.g.

更多一些细节

Thread t = new Thread();

In fact thread is started when you call start() method of java.lang.Thread class e.g. t.start() will start the thread. It puts your thread in RUNNABLE state and when thread scheduler assign CPU to this thread, it executes run() method.  By default run() method Thread class is empty, so you need to override it to do some meaningful task.

That’s all on important points related to Thread in Java. You can also suggests points, which you think its been missed here and I will include them in this list to make it more comprehensive and useful. I will also aim to keep it updated with more points once and when I recall or get aware of any stuff related to thread in Java. Last but not the least Effective Java book also got some good advice about synchronization and threads, worth reading for all kinds of Java developers

Read more: http://java67.blogspot.com/2014/01/10-points-about-thread-and-javalangthread-in-java.html#ixzz3jiSDGDm5

发表评论

电子邮件地址不会被公开。