标签:private package 台电脑 计算机 public
在计算机领域中,我们说的并发(Concurrency)是指一系列任务的同时运行。如果一台电脑有多个处理器或者有一个多核处理器,这个同时性(Simultaneity)是真正意义的并发;但是如果一台电脑只有一个单核处理器,这个同时性并不是真正的并发
一、线程的创建和运行
继承Thread类,并覆盖run()方法
创建一个Runnable接口的类。使用带参数的Thread构造器来创建Thread对象。这个参数就是实现Runnable接口的类的一个对象
范例实现:
package org.test.concurrency; /** * @author kucs * * 创建一个实现Runnable接口的类。使用带参数的Thread构造器来创建对象 * 这个参数就是实现Runnable接口的类的一个对象 * */ public class Calculator implements Runnable { private int number; public Calculator(int number) { this.number = number; } @Override public void run() { // TODO Auto-generated method stub for(int i = 0;i < 10;i++){ System.out.printf("%s: %d * %d = %d\n", Thread.currentThread().getName(),number,i,i*number); } } } package org.test.concurrency; public class Main { public static void main(String[] args) { /* 创建一个执行10次的循环 * 每次循环创建一个Calculator对象和一个Thread对象 * 这个Thread对象使用刚创建的Calculator对象作为构造器的参数 * 然后调用刚创建的Thread对象的start()方法 */ for(int i = 0;i < 10;i++){ Calculator calculator = new Calculator(i); Thread thread = new Thread(calculator); thread.start(); } } }
运行结果
当调用Thread对象的start()方法时,另一个执行线程将被创建。
如果某一个线程调用了System.exit()指令来结束程序的执行,所有的线程都将结束
对于一个实现了Runable接口的类来说,创建Thread对象并不会创建一个新的执行线程;同样的,调用它的run()方法,也不会创建一个新的线程。只有调用它的start()方法,才会创建一个新的执行线程。
二、线程信息的获取和设置
Thread类有一些保存信息的属性。这些属性可以用来标识线程的状态或者控制线程的优先级。
ID:保存了线程唯一的标识符
Name:保存了线程名
Priority:保存了线程对象的优先级。线程的优先级从1到10逐次递增。不建议改变线程优先级
Status:保存了线程的状态。在java中,线程有6中状态:new,runnable,blocked,waiting,time waiting或者terminated
jdk6版本的的Thread部分源码
public class Thread implements Runnable { /* Make sure registerNatives is the first thing <clinit> does. */ private static native void registerNatives(); static { registerNatives(); } private char name[]; private int priority; private Thread threadQ; private long eetop; /* Whether or not to single_step this thread. */ private boolean single_step; /* Whether or not the thread is a daemon thread. */ private boolean daemon = false; /* JVM state */ private boolean stillborn = false; /* What will be run. */ private Runnable target; /* The group of this thread */ private ThreadGroup group; /* The context ClassLoader for this thread */ private ClassLoader contextClassLoader; /* The inherited AccessControlContext of this thread */ private AccessControlContext inheritedAccessControlContext; /* For autonumbering anonymous threads. */ private static int threadInitNumber; private static synchronized int nextThreadNum() { return threadInitNumber++; } /* ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. */ ThreadLocal.ThreadLocalMap threadLocals = null; private long stackSize; /* * JVM-private state that persists after native thread termination. */ private long nativeParkEventPointer; /* * Thread ID */ private long tid;
我们对Main类进行改造,代码如下
package org.test.concurrency; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.lang.Thread.State; public class Main { public static void main(String[] args) { /* * 创建一个容量为10的线程数组,用来存储线程 创建一个容量为10的Thread.State数组,用来存储线程状态 */ Thread[] threads = new Thread[10]; Thread.State[] states = new Thread.State[10]; /* * 创建一个容量为10的Calculator对象数组,为每个对象都设置不同的数字 * 然后使用它们作为Thread构造器的参数来创建10个线程对象。 将5个线程优先级设置为最高,5个设置为最低 */ 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); } /* * 创建一个PrintWriter对象,用来把线程的状态写入文件 */ try { File file = new File("D:\\thread_log.txt"); if(!file.exists()){ file.createNewFile(); } FileWriter fw = new FileWriter(file); PrintWriter pw = new PrintWriter(fw); for (int i = 0; i < 10; i++) { // System.out.println("Main : Status of Thread " + i + ":" + threads[i].getState()); pw.println("Main : Status of Thread " + i + ":" + threads[i].getState()); states[i] = threads[i].getState(); } /* 开始执行10个线程 */ 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() != states[i]){ writeThreadInfo(pw,threads[i],states[i]); } } } finish = true; for(int i = 0;i<10;i++){ finish = finish && (threads[i].getState() == State.TERMINATED); } pw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private static void writeThreadInfo(PrintWriter pw, Thread thread, State state) { // TODO Auto-generated method stub 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 :", "***************************\n"); } }
运行结果
Main : Status of Thread 0:NEW Main : Status of Thread 1:NEW Main : Status of Thread 2:NEW Main : Status of Thread 3:NEW Main : Status of Thread 4:NEW Main : Status of Thread 5:NEW Main : Status of Thread 6:NEW Main : Status of Thread 7:NEW Main : Status of Thread 8:NEW Main : Status of Thread 9:NEW Main : Id 9 - Thread 0 Main : Priority: 10 Main : old State: NEW Main :Main : Id 10 - Thread 1 Main : Priority: 1 Main : old State: NEW Main :Main : Id 11 - Thread 2 Main : Priority: 10 Main : old State: NEW Main :Main : Id 12 - Thread 3 Main : Priority: 1 Main : old State: NEW Main :Main : Id 13 - Thread 4 Main : Priority: 10 Main : old State: NEW Main :Main : Id 14 - Thread 5 Main : Priority: 1 Main : old State: NEW Main :Main : Id 15 - Thread 6
三、线程的中断
Java提供了线程中断机制,我们可以使用它来结束一个线程。这种机制要求检查它是否被中断了,然后决定是不是响应这个中断请求。线程忽略中断请求并继续执行。我们用isInterrupted()方法来检查线程是否被中断。如果isInterrupted()返回值是true,则表示线程中断了。我们用thread.interrupt()来中断线程。
四、线程的休眠和恢复
通过线程的sleep()方法来打到让线程休眠的状态。线程休眠状态下不占用计算机任何资源。sleep()方法接受整形数值作为参数,表明线程挂起执行的毫秒数。
sleep()方法的另一种使用方式是通过TimeUnit枚举类元素调用。这个方法也使用Thread类的sleep()方法来使当前线程休眠。
五、等待线程的终止
在一些情形下我们必须等待线程的终止。为了达到这个目的,我们使用Thread的join()方法。当一个线程对象的join()方法被调用时,调用它的线程将被挂起,直到这个线程对象完成它的任务。
六、守护线程
Java里有一种特殊的线程叫守护线程(Daemon)。这种线程的优先级很低,通常来说,当同一个应用程序中没有其他线程运行的时候,守护线程才运行。当守护线程是程序中唯一运行的程序时,守护线程执行结束后,JVM也就结束了这个程序。
通常守护线程是无限循环的,以等待服务请求或者执行线程的任务。他们不能做重要的工作,因为我们不可能知道守护线程什么时候能够获取CPU时间片,并且在没有其他线程运行的时候,守护线程随时可能结束。一个典型的守护线程是Java的垃圾回收器(Garbage Collector)。
七、线程的分组
Java提供ThreadGroup类表示一组线程。线程组可以包含线程对象,可以包括其他的线程组对象,它是一个树形结构。相似内容请看Java多线程基础
本文出自 “阿酷博客源” 博客,请务必保留此出处http://aku28907.blog.51cto.com/5668513/1788953
标签:private package 台电脑 计算机 public
原文地址:http://aku28907.blog.51cto.com/5668513/1788953