`

Thread的实现

    博客分类:
  • JAVA
 
阅读更多
Making a Thread
A thread in Java begins as an instance of java.lang.Thread. For the exam, you’ll need to know, at a minimum, the following methods:
start()
yield()
sleep()
run()

You can define and instantiate a thread in one of two ways:
■ Extend the java.lang.Thread class
■ Implement the Runnable interface

方法一:Extending java.lang.Thread
The simplest way to define code to run in a separate thread is to
■ Extend the Thread class.
■ Override the run() method.
下面的例子示例了通过此方法实现的一个thread:
class MyThread extends Thread {
public void run() {
System.out.println("Important job running in MyThread");
}
}


方法二:Implementing java.lang.Runnable
通过实现java.lang.Runnable接口,亦可以定义一个thread,示例如下:
class MyRunnable implements Runnable {
public void run() {
System.out.println("Important job running in MyRunnable");
}
}

注意:因为是implements一个interface,因此你必须实现其public void run();方法(Runnable接口只有这一个方法)

对应于Define a thread的两种方法,Instantiating a thread也分别有两种方法:
方法一
如果你的thread是通过extends java.lang.Thread的方法获得,那么实例化一个Thread就非常简单:
MyThread t = new MyThread();  //这里的MyThread extends Thread的class

方法二
如果你的thread是通过implements Runnable接口的方法获得,那么实例化一个thread就稍微复杂一些,分为两个步骤:
1.MyRunnable  r = new MyRunnable();  //这里的MyRunnable是implements Runnable的class
2.Thread t = new Thread(r);             //将你的Runnable class传递给一个java.lang.Thread class
                                    //因为只有java.lang.Thread才有用来启动线程的start()
注意:你可以将一个Runnable传递给多个Thread实例,例如:
public class TestThreads {
public static void main (String [] args) {
MyRunnable r = new MyRunnable();  //带有任务(run()方法)的Runnable
Thread foo = new Thread(r);        //创建了三个Thread
Thread bar = new Thread(r);
Thread bat = new Thread(r);
}
}

上例中:三个Thread运行的任务是独立(三个Thread各自的call stack)且相同的(任务内容是一样的)。


你必须知道Thread的其它形式的构造函数
■ Thread()
■ Thread(Runnable target)
■ Thread(Runnable target, String name)
■ Thread(String name)
■ Thread(ThreadGroup group, Runnable target)
■ Thread(ThreadGroup group, Runnable target, String name)
■ Thread(ThreadGroup group, String name)


Thread的几个有用的方法:
1. public static Thread currentThread() :Returns a reference to the currently executing thread object.
2. public final void setName(String name):Changes the name of this thread to be equal to the argument name.
3. public final String getName():Returns this thread's name.


Methods from the java.lang.Thread Class Some of the methods that can help us influence thread scheduling are as follows:
public static void sleep(long millis) throws InterruptedException
public static void yield()
public final void join() throws InterruptedException
public final void setPriority(int newPriority)

Note that both sleep() and join() have overloaded versions not shown here.

Methods from the java.lang.Object Class Every class in Java inherits the following three thread-related methods:
public final void wait() throws InterruptedException
public final void notify()
public final void notifyAll()

The wait() method has three overloaded versions (including the one listed here).

Thread States
A thread can be only in one of five states

■ New This is the state the thread is in after the Thread instance has been instantiated, but the start() method has not been invoked on the thread. It is a live Thread object, but not yet a thread of execution. At this point, the thread is considered not alive. 线程实例(java.lang.thread或者其subclass)对象被创建,但是其start()方法还没有被调用。此时线程还不是活动的(alive).

■ Runnable This is the state a thread is in when it’s eligible to run, but the scheduler has not selected it to be the running thread. A thread first enters the runnable state when the start() method is invoked, but a thread can also return to the runnable state after either running or coming back from a blocked, waiting, or sleeping state. When the thread is in the runnable state, it is considered alive. 此时线程已经满足了所有运行所需的条件,只等到thread scheduler选中它就可以运行了。线程第一次进入Runnable状态的标志是,该线程的start()方法被调用。但是这并不是线程进入Runnable状态的唯一方法,处于Running状态和Blocking状态的线程也可以返回到Runnable状态。此时线程是活动的(alive).

■ Waiting/blocked/sleeping OK, so this is really three states combined into one, but they all have one thing in common: the thread is still alive, but is currently not eligible to run. In other words, it is not runnable, but it might return to a runnable state later if a particular event occurs. 1. A thread may be blocked waiting for a resource (like I/O or an object’s lock), in which case the event that sends it back to runnable is the availability of the resource—for example, if data comes in through the input stream the thread code is reading from, or if the object’s lock suddenly becomes available. 2. A thread may be sleeping because the thread’s run code tells it to sleep for some period of time, in which case the event that sends it back to runnable is that it wakes up because its sleep time has expired. 3.Or the thread may be waiting, because the thread’s run code causes it to wait, in which case the event that sends it back to runnable is that another thread sends a notification that it may no longer be necessary for the thread to wait. The important point is that one thread does not tell another thread to block. 也就是说,导致线程Blocking/Sleeping/Waiting的原因都是线程自身代码运行中遇到的,而其它的Thread并不能够通知/告诉/要求当前运行的线程被Block。There is a method, suspend(), in the Thread class, that lets one thread tell another to suspend, but the suspend() method has been deprecated and won’t be on the exam (nor will its counterpart resume()). There is also a stop() method, but it too has been deprecated and we won’t even go there. Both suspend() and stop() turned out to be very dangerous, so you shouldn’t use them and again, because they’re deprecated, they won’t appear on the exam. Don’t study ‘em, don’t use ‘em. Note also that a thread in a blocked state is still considered to be alive. 值得注意的是,处于Blocking状态的thread仍然是活动的(alive).


■ Dead A thread is considered dead when its run() method completes. It may still be a viable Thread object, but it is no longer a separate thread of execution. Once a thread is dead, it can never be brought back to life! (The whole “I see dead threads” thing.) If you invoke start() on a dead Thread instance, you’ll get a runtime (not compiler) exception. And it probably doesn’t take a rocket scientist to tell you that if a thread is dead, it is no longer considered to be alive.


Thread Priorities and Yield
要知道,不同的JVM实现的线程调度机制不同,有的实行优先级抢占策略,有的实行时间片轮转策略。
通常每个thread都有自己的优先级—priority。一般priority用1到10的数字来表示。
注意:Thread类有以下关于线程priority的static final常量:
public static final int MAX_PRIORITY
The maximum priority that a thread can have.
public static final int MIN_PRIORITY
The minimum priority that a thread can have.
public static final int NORM_PRIORITY
The default priority that is assigned to a thread.

Setting a Thread’s Priority
A thread gets a default priority that is the priority of the thread of execution that creates it.
默认地,一个线程的优先级是和创建它的线程相同的。例如:
public class TestThreads {
public static void main (String [] args) {
MyThread t = new MyThread();
}
}

the thread referenced by t 和 the main thread具有相同的优先级, since the main thread is executing the code that creates the MyThread instance.

当然你也可以通过Thread实例的public final void setPriority(int newPriority)方法来为一个线程设定优先级。例如:
FooRunnable r = new FooRunnable();
Thread t = new Thread(r);
t.setPriority(8);  //为Thread t设定的优先级为8
t.start();


The default priority is 5


关于yield()方法
也就是说,Thread的yield()方法的作用就是让当前线程暂时停止执行,返回到Runnable状态。以便其它的与之具有相同优先级的处于Runnable状态的线程可以获得调度。
但是这一原则性的策略的执行并不会得到JVM的保证。因为,yield()虽然可以保证使得当前正在执行的线程进入Runnable状态,但是并不会保证进入Runnable的该线程不会被thread scheduler再次选中,重新进入Running状态。因为,被yield()方法放进Runnable Pool的该进程会和Runnable Pool中具有相同优先级的进程一样被thread scheduler来考量

The Join() Method

1.public final void join() throws InterruptedException
   Waits for this thread to die
2.public final void join(long millis) throws InterruptedException
Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.
3.public final void join(long millis,int nanos) throws InterruptedException
Waits at most millis milliseconds plus nanos nanoseconds for this thread to die

Synchronizing Code
Write code using synchronized wait, notify, and notifyAll to protect against concurrent access problems and to communicate between threads.

So how do you protect the data? You must do two things:
■ Mark the variables private
■ Synchronize the code that modifies the variables


关于lock和synchronized我们应该记住下面的要点:
■ Only methods can be synchronized, not variables.
只有method可以被synchronized,变量不可以
■ Each object has just one lock.
每个对象只有一个机锁
■ Not all methods in a class must be synchronized. A class can have both synchronized and nonsynchronized methods.
一个class中并非所有的method都必须是synchronized的。一个class可以有synchronized方法,也可以有nonsynchronized方法
■ If two methods are synchronized in a class, only one thread can be accessing one of the two methods. In other words, once a thread acquires the lock on an object, no other thread can enter any of the synchronized methods in that class (for that object).
机锁具有独占性,一旦被一个Thread获得,其他的thread就不能够再拥有。
■ If a class has both synchronized and nonsynchronized methods, multiple threads can still access the nonsynchronized methods of the class! If you have methods that don’t access the data you’re trying to protect, then you don’t need to mark them as synchronized. Synchronization is a performance hit, so you don’t want to use it without a good reason.
Nonsynchronized方法并不会导致对象的lock被激活。但是过多的使用synchronized method会影响性能,所以要慎用。
■ If a thread goes to sleep, it takes its locks with it.
一个线程进入Sleeping状态,他不会释放他所拥有的其它对象的lock
■ A thread can acquire more than one lock.
一个线程可以同时获得多个对象的机锁(lock)


常见的几个Methods小结:
java.lang.Runnable(inerface):
1.public void run()
java.lang.Thread:
java.lang.Thread implements java.lang.Runnable
1.public void start()
2.public void run()   from java.lang.Runnable
3.sleep()   throws InterruptedException
   public static void sleep(long millis) throws InterruptedException
   public static void sleep(long millis,int nanos) throws InterruptedException
4. public static void yield()
5. join() throws InterruputedException
   public final void join() throws InterruptedException
   public final void join(long millis) throws InterruptedException
   public final void join(long millis,int nanos) throws InterruptedException
java.lang.Object
1. Wait() throws InterruptedException,必须在synchronized code中,否则掷出异常IllegalMonitorStateException说明必须拥有lock,注意此异常不需捕捉
public final void wait() throws InterruptedException
public final void wait(long timeout) throws InterruptedException
public final void wait(long timeout,int nanos) throws InterruptedException
2. notify(),否则掷出异常IllegalMonitorStateException说明必须拥有lock,注意此异常不需捕捉
   public final void notify()
3. notifyAll(),否则掷出异常IllegalMonitorStateException说明必须拥有lock,注意此异常不需捕捉
   public final void notifyAll()





































分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics