Java Thread: Creation and Start

Java Thread: Creation and Start
 
SCJP5 study notes
 
First, define the thread
 
1. Extend the java.lang.Thread class.
 
There is a run() method in this class, you should pay attention to its usage:
public void run()
If the thread was constructed using a standalone Runnable run object, the Runnable object's run method is called; otherwise, the method does nothing and returns.
 
Thread Subclasses should override this method.
2. Implement the java.lang.Runnable interface.
 
void run ()
When a thread is created Runnable with an , starting the thread causes the object's run methods to be called in a separate thread of execution.
 
run The general contract of a method is that it may perform any desired operation.
 
Second, instantiate the thread
 
1. If it is a thread that extends the java.lang.Thread class, it can be directly new.
 
2. If it is a class that implements the java.lang.Runnable interface, use the construction method of Thread:
Thread(Runnable target)
Thread(Runnable target, String name)
Thread(ThreadGroup group, Runnable target)
Thread(ThreadGroup group, Runnable target, String name)
Thread(ThreadGroup group, Runnable target, String name, long stackSize)
 
3. Start the thread
 
Call the start() method on the thread's Thread object, not run() or other methods.
 
Before calling the start() method: the thread is in a new state, which means that there is a Thread object, but there is no real thread.
 
After calling the start() method: a complicated series of things happens
start a new thread of execution (with a new call stack);
The thread transitions from the new state to the runnable state;
When the thread gets a chance to execute, its target run() method will run.
 
Note: There is nothing special about the run() method in Java. Like the main() method, it's just that the new thread knows the method name (and signature) to call. Therefore, it is legal to call the run method on a Runnable or a Thread. But does not start a new thread.
 
 
4. Examples
 
1. An example of multithreading that implements the Runnable interface
/**
* 实现Runnable接口的类
*
* @author leizhimin 2008-9-13 18:12:10
*/

public class DoSomething implements Runnable {
     private String name;

     public DoSomething(String name) {
         this .name = name;
    }

     public void run() {
         for ( int i = 0; i < 5; i++) {
             for ( long k = 0; k < 100000000; k++) ;
            System.out.println(name + ": " + i);
        }
    }
}
 
/**
* Test the multithreaded program implemented by the Runnable class
*
* @author leizhimin 2008-9-13 18:15:02
*/

public class TestRunnable {
     public static void main(String[] args) {
        DoSomething ds1 = new DoSomething( "Asan" );
        DoSomething ds2 = new DoSomething( "Li Si" );

        Thread t1 = new Thread(ds1);
        Thread t2 = new Thread(ds2);

        t1.start();
        t2.start();
    }
}
 
Results of the:
Li Si:
0A San:
0Li Si: 1A
San:
1Li Si:
2Li Si:
3A San:
2Li Si:
4A San:
3A San: 4

Process finished with exit code 0
 
2. An example of multi-threading implemented by extending the Thread class
 
/**
* 测试扩展Thread类实现的多线程程序
*
* @author leizhimin 2008-9-13 18:22:13
*/

public class TestThread extends Thread{
     public TestThread(String name) {
         super(name);
    }

     public void run() {
         for( int i = 0;i<5;i++){
             for( long k= 0; k <100000000;k++);
            System.out.println( this.getName()+ " :"+i);
        }
    }

     public static void main(String[] args) {
        Thread t1 = new TestThread( "阿三");
        Thread t2 = new TestThread( "李四");
        t1.start();
        t2.start();
    }
}
 
执行结果:
阿三 :0
李四 :0
阿三 :1
李四 :1
阿三 :2
李四 :2
阿三 :3
阿三 :4
李四 :3
李四 :4

Process finished with exit code 0
 
对于上面的多线程程序代码来说,输出的结果是不确定的。其中的一条语句for(long k= 0; k <100000000;k++);是用来模拟一个非常耗时的操作的。
 
五、一些常见问题
 
1、线程的名字,一个运行中的线程总是有名字的,名字有两个来源,一个是虚拟机自己给的名字,一个是你自己的定的名字。在没有指定线程名字的情况下,虚拟机总会为线程指定名字,并且主线程的名字总是mian,非主线程的名字不确定。
2、线程都可以设置名字,也可以获取线程的名字,连主线程也不例外。
3、获取当前线程的对象的方法是:Thread.currentThread();
4、在上面的代码中,只能保证:每个线程都将启动,每个线程都将运行直到完成。一系列线程以某种顺序启动并不意味着将按该顺序执行。对于任何一组启动的线程来说,调度程序不能保证其执行次序,持续时间也无法保证。
5、当线程目标run()方法结束时该线程完成。
6、一旦线程启动,它就永远不能再重新启动。只有一个新的线程可以被启动,并且只能一次。一个可运行的线程或死线程可以被重新启动。
7、线程的调度是JVM的一部分,在一个CPU的机器上上,实际上一次只能运行一个线程。一次只有一个线程栈执行。JVM线程调度程序决定实际运行哪个处于可运行状态的线程。
众多可运行线程中的某一个会被选中做为当前线程。可运行线程被选择运行的顺序是没有保障的。
8、尽管通常采用队列形式,但这是没有保障的。队列形式是指当一个线程完成“一轮”时,它移到可运行队列的尾部等待,直到它最终排队到该队列的前端为止,它才能被再次选中。事实上,我们把它称为可运行池而不是一个可运行队列,目的是帮助认识线程并不都是以某种有保障的顺序排列唱呢个一个队列的事实。
9、尽管我们没有无法控制线程调度程序,但可以通过别的方式来影响线程调度的方式。

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327007737&siteId=291194637