Java多线程实现方式:1.实现Runnable接口2.继承Thread类,虽然是比较基础的知识点,作为学习记录写下来,高手略过!
1.实现Runnable接口
1) RunnableDemo类
package com.wicresoft.demo;
public class RunnableDemo implements Runnable {
private Thread t;
private String threadName;
RunnableDemo(String name){
this.threadName = name;
System.out.println("Creating " + threadName);
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Running " + threadName);
try{
for(int i = 4; i > 0; i--){
System.out.println("Thread: " + threadName + "," + i);
//thread sleep for a while
Thread.sleep(50);
}
}catch(InterruptedException e){
System.out.println("Running " + threadName);
}
System.out.println("Thread " + threadName + "exiting.");
}
public void start(){
System.out.println("Starting " + threadName );
if (t == null){
t = new Thread (this, threadName);
t.start ();
}
}
}
2)TestThread类
package com.wicresoft.demo;
public class TestThread {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
RunnableDemo R1 = new RunnableDemo("Thread-1");
R1.start();
RunnableDemo R2 = new RunnableDemo("Thread-2");
R2.start();
}
}
3)输出
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread Thread-1,4
Running Thread-2
Thread Thread-2,4
Thread Thread-1,3
Thread Thread-2,3
Thread Thread-2,2
Thread Thread-1,2
Thread Thread-2,1
Thread Thread-1,1
Thread Thread-2 exiting.
Thread Thread-1 exiting.
2.继承Thread
1)ThreadDemo
package com.wicresoft.demo2;
public class ThreadDemo extends Thread {
private Thread t;
private String threadName;
ThreadDemo(String name){
this.threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
try {
for(int i = 4; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start(){
System.out.println("Starting " + threadName );
if (t == null){
t = new Thread (this, threadName);
t.start ();
}
}
}
2)TestThread类
package com.wicresoft.demo2;
public class TestThread {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ThreadDemo T1 = new ThreadDemo( "Thread-1");
T1.start();
ThreadDemo T2 = new ThreadDemo( "Thread-2");
T2.start();
}
}
3)输出
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.
3.关于线程优先级
Java线程的优先级是一个整数,其取值范围是1 (Thread.MIN_PRIORITY ) - 10 (Thread.MAX_PRIORITY ),默认优先级是5.
线程组最大优先级的设定:
->系统线程组的最大优先级默认为Thread.MAX_PRIORITY
->创建线程组的时候其最大优先级默认为父线程组(如果未指定父线程组,则其父线程组默认为当前线程所属线程组)的最大优先级
->可以通过setMaxPriority更改最大优先级,但无法超过父线程组的最大优先级
对于线程优先级,我们需要注意:
* Thread.setPriority()可能根本不做任何事情,这跟你的操作系统和虚拟机版本有关
* 线程优先级对于不同的线程调度器可能有不同的含义,可能并不是你直观的推测。特别地,优先级并不一定是指CPU的分享。在UNIX系统,优先级或多或少可以认为是CPU的分配,但Windows不是这样
* 线程的优先级通常是全局的和局部的优先级设定的组合。Java的setPriority()方法只应用于局部的优先级。换句话说,你不能在整个可能的范围 内设定优先级。(这通常是一种保护的方式,你大概不希望鼠标指针的线程或者处理音频数据的线程被其它随机的用户线程所抢占)
* 不同的系统有不同的线程优先级的取值范围,但是Java定义了10个级别(1-10)。这样就有可能出现几个线程在一个操作系统里有不同的优先级,在另外一个操作系统里却有相同的优先级(并因此可能有意想不到的行为)
* 操作系统可能(并通常这么做)根据线程的优先级给线程添加一些专有的行为(例如”only give a quantum boost if the priority is below X“)。这里再重复一次,优先级的定义有部分在不同系统间有差别。
* 大多数操作系统的线程调度器实际上执行的是在战略的角度上对线程的优先级做临时操作(例如当一个线程接收到它所等待的一个事件或者I/O),通常操作系统知道最多,试图手工控制优先级可能只会干扰这个系统。
* 你的应用程序通常不知道有哪些其它进程运行的线程,所以对于整个系统来说,变更一个线程的优先级所带来的影响是难于预测的。例如你可能发现,你有一个预期 为偶尔在后台运行的低优先级的线程几乎没有运行,原因是一个病毒监控程序在一个稍微高一点的优先级(但仍然低于普通的优先级)上运行,并且无法预计你程序 的性能,它会根据你的客户使用的防病毒程序不同而不同。
实际编码注意事项
不要假定高优先级的线程一定先于低优先级的线程执行,不要有逻辑依赖于线程优先级,否则可能产生意外结果!