创建线程两种方式
1.继承Thread 类,重写run()方法
2.创建实现Runnable 接口的类,然后创建参数为此类的Thread类对象
例:
public class Calculator implements Runnable {
private int number;
public Calculator(int number) {
this.number=number;
}
@Override
public void run() {
for (int i=1; i<=10; i++){
System.out.printf("%s: %d * %d = %d\n",Thread.currentThread().getName(),number,i,i*number);
}
}
public static void main(String[] args) {
for (int i=1; i<=10; i++){
Calculator calculator=new Calculator(i);
Thread thread=new Thread(calculator);
thread.start();
}
}
}此程序运行11个线程,如果没有线程调用System.exit()方法,那么所有程序退出此java程序才终止。创建thread类或者直接调用run方法不会创建线程,只有调用 start() 方法才会调用新的线程
获取或者设置线程属性
1.ID: 这个属性存储一个线程的唯一标识符
2.Name: 这个属性存储一个线程的名字
3.Priority: 这个属性存储线程对象优先级。线程优先级取值为1到10,1为最低优先级10为最高优先级。不推荐修改线程的优先级,但是是可以修改的,如果你想这么做的话
4.Status: 这个属性存储线程的状态。一个线程可以是下面六种状态之一:初始,运行,阻塞,等待,超时等待,终止
public class Calculator implements Runnable {
private int number;
public Calculator(int number) {
this.number=number;
}
@Override
public void run() {
for (int i=1; i<=10; i++){
System.out.printf("%s: %d * %d = %d\n",Thread.currentThread().getName(),number,i,i*number);
}
}
private static void writeThreadInfo(PrintWriter pw, Thread thread, Thread.State state) {
pw.printf("Main : Id %d - %s\n",thread.getId(),thread.getName());
pw.printf("Main : Priority: %d\n",thread.getPriority());
pw.printf("Main : Old State: %s\n",state);
pw.printf("Main : New State: %s\n",thread.getState());
pw.printf("Main : ************************************\n");
}
public static void main(String[] args) throws IOException {
Thread threads[]=new Thread[10];
Thread.State status[]=new Thread.State[10];
for (int i=0; i<10; i++){
threads[i]=new Thread(new Calculator(i));
if ((i%2)==0){
threads[i].setPriority(Thread.MAX_PRIORITY);
} else {
threads[i].setPriority(Thread.MIN_PRIORITY);
}
threads[i].setName("Thread "+i);
}
try (FileWriter file = new FileWriter(".\\data\\log.txt");
PrintWriter pw = new PrintWriter(file)){
for (int i=0; i<10; i++) {
pw.println("Main : Status of Thread " + i + " : " + threads[i].getState());
status[i] = threads[i].getState();//此时线程状态全为NEW
}
for (int i=0; i<10; i++){
threads[i].start();
}
boolean finish=false;
while (!finish) {
for (int i=0; i<10; i++){
if (threads[i].getState()!=status[i]) {
writeThreadInfo(pw, threads[i],status[i]);
status[i]=threads[i].getState();
}
}
finish=true;
for (int i=0; i<10; i++){
finish=finish &&(threads[i].getState()== Thread.State.TERMINATED);
}
}
}
}
}运行程序你可以看到每个进程从初始到终止打印的状态。优先级高的线程会比优先级低的先完成。线程名字可以修改或者使用默认值Thread-XX。没有setId()和setStatus() 方法。
中断一个线程
public class PrimeGenerator extends Thread {
@Override
public void run() {
long number=1L;
while (true) {
if (isPrime(number)) {
System.out.printf("Number %d is Prime",number);
}
if (isInterrupted()) {
System.out.printf("The Prime Generator has been Interrupted");
return;
}
number++;
}
}
private boolean isPrime(long number) {
if (number <=2) {
return true;
}
for (long i=2; i<number; i++){
if ((number % i)==0) {
return false;
}
}
return true;
}
public static void main(String[] args) {
Thread task=new PrimeGenerator();
task.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
task.interrupt();
}
}task线程一直执行,直到interrupt()方法调用才会自己终止执行。线程也可以忽略interrupt属性但是不推荐。
另外一种抛异常中断方式
public class FileSearch implements Runnable {
private String initPath;
private String fileName;
public FileSearch(String initPath, String fileName) {
this.initPath = initPath;
this.fileName = fileName;
}
@Override
public void run() {
File file = new File(initPath);
if (file.isDirectory()) {
try {
directoryProcess(file);
} catch (InterruptedException e) {
System.out.printf("%s: The search has been interrupted",Thread.currentThread().getName());
}
}
}
private void directoryProcess(File file) throws InterruptedException {
File list[] = file.listFiles();
if (list != null) {
for (int i = 0; i < list.length; i++) {
if (list[i].isDirectory()) {
directoryProcess(list[i]);
} else {
fileProcess(list[i]);
}
}
}
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
private void fileProcess(File file) throws InterruptedException {
if (file.getName().equals(fileName)) {
System.out.printf("%s : %s\n",Thread.currentThread().getName() ,file.getAbsolutePath());
}
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
public static void main(String[] args) {
FileSearch searcher=new FileSearch(“C:\”,“autoexec.bat”);
Thread thread=new Thread(searcher);
thread.start();
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
}