文章目录
线程的状态
NEW状态是线程实例化后还从未执行start()方法时的状态,而RUNNABLE状态是线程进入运行的状态,TERMINATED是线程被销毁时的状态。
并发:CPU分时轮询的执行线程。
并行:同一个时刻同时在执行。
package multiply.com.test;
public class Run {
public static void main(String[] args) {
try {
MyThread t = new MyThread();
System.out.println(" 1 Main1 method state : " + t.getState());
Thread.sleep(1000);
t.start();
Thread.sleep(1000);
System.out.println(" 2 Main1 method state : " + t.getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package multiply.com.test;
public class MyThread extends Thread {
public MyThread() {
System.out.println("Constuctor method state : " + Thread.currentThread().getState());
}
@Override
public void run() {
super.run();
System.out.println(" Run1 method state : " + Thread.currentThread().getState());
}
}
Constuctor method state : RUNNABLE
1 Main1 method state : NEW
Run1 method state : RUNNABLE
2 Main1 method state : TERMINATED
构造方法中打印出的日志其实是显示main主线程的状态为RUNNABLE。线程状态TIMED_WAITING代表线程执行了Thread.sleep()方法。状态WAITING是线程执行了 Object.wait()方法后所处的状态。BLOCKED状态出现在某一个线程在等待锁的时候。
线程组
线程对象关联线程组:1级关联
所谓的1级关联就是父对象中有子对象,但并不创建子孙对象。
package multiply.com.test;
public class Run {
public static void main(String[] args) {
ThreadA a = new ThreadA();
ThreadB b = new ThreadB();
ThreadGroup group = new ThreadGroup("X process group!");
Thread aThread = new Thread(group, a);
Thread bThread = new Thread(group, b);
aThread.start();
bThread.start();
System.out.println("Active process number : " + group.activeCount());
System.out.println(" process name : " + group.getName());
}
}
package multiply.com.test;
public class ThreadA extends Thread {
@Override
public void run() {
super.run();
try {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("Thread name : " + Thread.currentThread().getName());
Thread.sleep(3000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package multiply.com.test;
public class ThreadB extends Thread {
@Override
public void run() {
super.run();
try {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("Thread name : " + Thread.currentThread().getName());
Thread.sleep(3000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
线程对象关联线程组:多级关联
所谓的多级关联就是父对象中有子对象,子对象中再创建子对象。
获取根线程组
线程组里面加线程组
ThreadGroup newGroup = new ThreadGroup(Thread.currentThread ().getThreadGroup () , “newGroup” );
组内的线程批量停止
递归和非递归取得组内对象
传入false就是只取得子组
使线程具有有序性
正常的情况下,线程在运行时多个线程之间执行任务的时机是无序的。可以通过改造代码的方式使它们运行具有有序性。
package multiply.com.test;
public class Run {
public static void main(String[] args) {
Object lock = new Object();
MyThread a = new MyThread(lock, "A", 1);
MyThread b = new MyThread(lock, "B", 2);
MyThread c = new MyThread(lock, "C", 0);
a.start();
b.start();
c.start();
}
}
package multiply.com.test;
public class MyThread extends Thread {
private Object lock;
private String showChar;
private int showNumPosition;
private int printCount = 0;
volatile private static int addNumber = 1;
public MyThread(Object lock, String showChar, int showNumPosition) {
super();
this.lock = lock;
this.showChar = showChar;
this.showNumPosition = showNumPosition;
}
@Override
public void run() {
try {
synchronized (lock) {
while (true) {
if (addNumber % 3 == showNumPosition) {
System.out.println("ThreadName=" + Thread.currentThread().getName()
+ " runCount=" + addNumber + " " + showChar);
lock.notifyAll();
addNumber++;
printCount++;
if (printCount == 3) {
break;
}
} else {
lock.wait();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
ThreadName=Thread-0 runCount=1 A
ThreadName=Thread-1 runCount=2 B
ThreadName=Thread-2 runCount=3 C
ThreadName=Thread-0 runCount=4 A
ThreadName=Thread-1 runCount=5 B
ThreadName=Thread-2 runCount=6 C
ThreadName=Thread-0 runCount=7 A
ThreadName=Thread-1 runCount=8 B
ThreadName=Thread-2 runCount=9 C
SimpleDateFormat非线程安全
package multiply.com.test;
import java.text.SimpleDateFormat;
public class Test {
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String[] dateStringArray = new String[] { "2000-01-01", "2000-01-02",
"2000-01-03", "2000-01-04", "2000-01-05", "2000-01-06",
"2000-01-07", "2000-01-08", "2000-01-09", "2000-01-10" };
MyThread[] threadArray = new MyThread[10];
for (int i = 0; i < 10; i++) {
threadArray[i] = new MyThread(sdf, dateStringArray[i]);
}
for (int i = 0; i < 10; i++) {
threadArray[i].start();
}
}
}
package multiply.com.test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MyThread extends Thread {
private SimpleDateFormat sdf;
private String dateString;
public MyThread(SimpleDateFormat sdf, String dateString) {
super();
this.sdf = sdf;
this.dateString = dateString;
}
@Override
public void run() {
try {
Date dateRef = sdf.parse(dateString);
String newDateString = sdf.format(dateRef).toString();
if (!newDateString.equals(dateString)) {
System.out.println("ThreadName=" + this.getName()
+ "报错了,日期字符串:" + dateString + " 转换成的日期为:"
+ newDateString);
}
} catch (ParseException e) {
e.printStackTrace();
}
}
}
ThreadLocal类能使线程绑定到指定的对象
线程中的异常处理
在Java的多线程技术中,可以对多线程中的异常进行“捕捉”,使用的是UncaughtExceptionHandler类,从而可以对发生的异常进行有效的处理。
方法setUncaughtExceptionHandler()是给指定线程对象设置的异常处理器。在Thread类中还可以使用setDefaultUncaughtExceptionHandler()方法对所有线程对象设置异常处理器,
线程组内异常处理
从运行的结果来看,在默认的情况下,线程组中的一个线程出现异常不会影响其他线程的运行。
如果想实现线程组内一个线程出现异常后全部线程都停止运行该如何实现呢?
package multiply.com.test;
public class Run {
public static void main(String[] args) {
MyThreadGroup group = new MyThreadGroup("My Thread Group!");
MyThread[] myThread = new MyThread[10];
for (int i = 0; i < myThread.length; i++) {
myThread[i] = new MyThread(group, "Thread " + (i + 1), "1");
myThread[i].start();
}
MyThread t = new MyThread(group, "Exception Thread ", "AA");
t.start();
}
}
package multiply.com.test;
public class MyThread extends Thread {
private String num;
public MyThread(ThreadGroup group, String name, String num) {
super(group, name);
this.num = num;
}
@Override
public void run() {
super.run();
int numInt = Integer.parseInt(num);
System.out.println(Thread.currentThread().getName() + " " + numInt);
while (!this.isInterrupted()) {
}
}
}
package multiply.com.test;
public class MyThreadGroup extends ThreadGroup {
public MyThreadGroup(String name) {
super(name);
}
@Override
public void uncaughtException(Thread t, Throwable e) {
super.uncaughtException(t, e);
this.interrupt();
}
}