1、Java 实例 – 查看线程是否存活:通过继承 Thread 类并使用 isAlive() 方法来检测一个线程是否存活。
public class Thread_Aliveextends Thread{
public void run() {
for (int i =0; i <2; i++) {
printMsg();
}
}
public void printMsg() {
Thread t = Thread.currentThread();
String name = t.getName();
System.out.println("name=" + name);
}
public static void main(String[] args) {
Thread_Alive tt =new Thread_Alive();
tt.setName("Thread");
System.out.println("before start(), tt.isAlive()=" + tt.isAlive());
tt.start();
System.out.println("just after start(), tt.isAlive()=" + tt.isAlive());
for (int i =0; i <10; i++) {
tt.printMsg();
}
System.out.println("The end of main(), tt.isAlive()=" + tt.isAlive());
}
}
执行结果:
2、Java 实例 – 获取当前线程名称:通过继承 Thread 类并使用 getName() 方法来获取当前线程名称。
public class Thread_GetName extends Thread{
public void run() {
for (int i =0; i <2; i++) {
printMsg();
}
}
public void printMsg() {
Thread t = Thread.currentThread();
String name = t.getName();
System.out.println("name=" + name);
}
public static void main(String[] args) {
Thread_GetName tt =new Thread_GetName();
tt.start();
for (int i =0; i <10; i++) {
tt.printMsg();
}
}
}
执行结果:
3、Java 实例 – 状态监测:通过继承 Thread 类并使用 currentThread.getName() 方法来监测线程的状态。
public class Thread_Testextends Thread{
boolean waiting=true;
boolean ready=false;
Thread_Test() {
}
public void run() {
String thrdName = Thread.currentThread().getName();
System.out.println(thrdName +" starting.");
while(waiting)
System.out.println("waiting:"+waiting);
System.out.println("waiting...");
startWait();
try {
Thread.sleep(10);
}
catch(Exception exc) {
System.out.println(thrdName +" interrupted.");
}
System.out.println(thrdName +" terminating.");
}
synchronized void startWait() {
try {
while(!ready) wait();
}
catch(InterruptedException exc) {
System.out.println("wait() interrupted");
}
}
synchronized void notice() {
ready =true;
notify();
}
}
······································································
public class Test_Main {
public static void main(String args[])throws Exception{
Thread_Test thrd =new Thread_Test();
thrd.setName("MyThread #1");
showThreadStatus(thrd);
thrd.start();
Thread.sleep(10);
showThreadStatus(thrd);
thrd.waiting =false;
Thread.sleep(10);
showThreadStatus(thrd);
thrd.notice();
Thread.sleep(10);
showThreadStatus(thrd);
while(thrd.isAlive())
System.out.println("alive");
showThreadStatus(thrd);
}
static void showThreadStatus(Thread thrd) {
System.out.println(thrd.getName() +"Alive:=" + thrd.isAlive() +" State:=" + thrd.getState());
}
}
执行结果:
4、Java 实例 – 线程优先级设置:通过setPriority() 方法来设置线程的优先级。
public class Thread_Prioritiesextends Thread{
private int countDown =3;
private volatile double d =0;
public Thread_Priorities(int priority) {
setPriority(priority);
start();
}
public String toString() {
return super.toString() +": " +countDown;
}
public void run() {
while(true) {
for(int i =1; i <100000; i++)
d =d + (Math.PI + Math.E) / (double)i;
System.out.println(this);
if(--countDown ==0)return;
}
}
public static void main(String[] args) {
new Thread_Priorities(Thread.MAX_PRIORITY);
for(int i =0; i <5; i++)
new Thread_Priorities(Thread.MIN_PRIORITY);
}
}
执行结果:
5、Java 实例 – 死锁及解决方法:
死锁:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。
java 死锁产生的四个必要条件:
1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用
2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
4、循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。
解决死锁问题的方法是:一种是用synchronized,一种是用Lock显式锁实现。
死锁:
public class Thread_LockAimplements Runnable{
public void run() {
try {
System.out.println(new Date().toString() +" LockA 开始执行");
while(true){
synchronized (Lock_Main.obj1) {
System.out.println(new Date().toString() +" LockA 锁住 obj1");
Thread.sleep(3000);// 此处等待是给B能锁住机会
synchronized (Lock_Main.obj2) {
System.out.println(new Date().toString() +" LockA 锁住 obj2");
Thread.sleep(60 *1000);// 为测试,占用了就不放
}
}
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
·····················································································
public class Thread_LockBimplements Runnable{
public void run() {
try {
System.out.println(new Date().toString() +" LockB 开始执行");
while(true){
synchronized (Lock_Main.obj2) {
System.out.println(new Date().toString() +" LockB 锁住 obj2");
Thread.sleep(3000);// 此处等待是给A能锁住机会
synchronized (Lock_Main.obj1) {
System.out.println(new Date().toString() +" LockB 锁住 obj1");
Thread.sleep(60 *1000);// 为测试,占用了就不放
}
}
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
·············································································
public class Lock_Main {
public static Stringobj1 ="obj1";
public static Stringobj2 ="obj2";
public static void main(String[] args) {
Thread_LockA la =new Thread_LockA();
new Thread(la).start();
Thread_LockB lb =new Thread_LockB();
new Thread(lb).start();
}
}
执行结果:
解决死锁:
public class Thread_LockAaimplements Runnable{
public void run() {
try {
System.out.println(new Date().toString() +" LockA 开始执行");
while (true) {
if (UnLock_Main.a1.tryAcquire(1, TimeUnit.SECONDS)) {
System.out.println(new Date().toString() +" LockA 锁住 obj1");
if (UnLock_Main.a2.tryAcquire(1, TimeUnit.SECONDS)) {
System.out.println(new Date().toString() +" LockA 锁住 obj2");
Thread.sleep(60 *1000);// do something
}else{
System.out.println(new Date().toString() +"LockA 锁 obj2 失败");
}
}else{
System.out.println(new Date().toString() +"LockA 锁 obj1 失败");
}
UnLock_Main.a1.release();// 释放
UnLock_Main.a2.release();
Thread.sleep(1000);// 马上进行尝试,现实情况下do something是不确定的
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
·········································································
public class Thread_LockBbimplements Runnable{
public void run() {
try {
System.out.println(new Date().toString() +" LockB 开始执行");
while (true) {
if (UnLock_Main.a2.tryAcquire(1, TimeUnit.SECONDS)) {
System.out.println(new Date().toString() +" LockB 锁住 obj2");
if (UnLock_Main.a1.tryAcquire(1, TimeUnit.SECONDS)) {
System.out.println(new Date().toString() +" LockB 锁住 obj1");
Thread.sleep(60 *1000);// do something
}else{
System.out.println(new Date().toString() +"LockB 锁 obj1 失败");
}
}else{
System.out.println(new Date().toString() +"LockB 锁 obj2 失败");
}
UnLock_Main.a1.release();// 释放
UnLock_Main.a2.release();
Thread.sleep(10 *1000);// 这里只是为了演示,所以tryAcquire只用1秒,而且B要给A让出能执行的时间,否则两个永远是死锁
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
········································································
public class UnLock_Main {
public static Stringobj1 ="obj1";
public static final Semaphorea1 =new Semaphore(1);
public static Stringobj2 ="obj2";
public static final Semaphorea2 =new Semaphore(1);
public static void main(String[] args) {
Thread_LockAa la =new Thread_LockAa();
new Thread(la).start();
Thread_LockBb lb =new Thread_LockBb();
new Thread(lb).start();
}
}
执行结果:
6、Java 实例 – 获取线程id:使用 getThreadId() 方法获取线程id。
public class ThreadIDextends ThreadLocal {
private int nextID;
public ThreadID() {
nextID =10001;
}
private synchronized Integer getNewID() {
Integer id =new Integer(nextID);
nextID++;
return id;
}
protected Object initialValue() {
print("in initialValue()");
return getNewID();
}
public int getThreadID() {
Integer id = (Integer) get();
return id.intValue();
}
private static void print(String msg) {
String name = Thread.currentThread().getName();
System.out.println(name +": " + msg);
}
}
····················································································
public class ID_Main extends Objectimplements Runnable{
private ThreadIDvar;
public ID_Main(ThreadID v) {
this.var = v;
}
public void run() {
try {
print("var getThreadID =" +var.getThreadID());
Thread.sleep(2000);
print("var getThreadID =" +var.getThreadID());
}catch (InterruptedException x) {
}
}
private static void print(String msg) {
String name = Thread.currentThread().getName();
System.out.println(name +": " + msg);
}
public static void main(String[] args) {
ThreadID tid =new ThreadID();
ID_Main shared =new ID_Main(tid);
try {
Thread threadA =new Thread(shared,"threadA");
threadA.start();
Thread.sleep(500);
Thread threadB =new Thread(shared,"threadB");
threadB.start();
Thread.sleep(500);
Thread threadC =new Thread(shared,"threadC");
threadC.start();
}catch (InterruptedException x) {
}
}
}
执行结果:
7、Java 实例 – 线程挂起:
public class Thread_Sleepingextends Thread{
private int countDown =3;
private static int threadCount =0;
public Thread_Sleeping() {
super("" + ++threadCount);
start();
}
public String toString() {
return "#" + getName() +": " +countDown;
}
public void run() {
while (true) {
System.out.println(this);
if (--countDown ==0)
return;
try {
sleep(100);
}
catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public static void main(String[] args)
throws InterruptedException {
for (int i =0; i <3; i++)
new Thread_Sleeping().join();
System.out.println("线程已被挂起");
}
}
执行结果:
8、Java 实例 – 终止线程:Java中原来在Thread中提供了stop()方法来终止线程,但这个方法是不安全的,所以一般不建议使用。该实例使用interrupt方法来终端线程,可分为两种情况:
(1)线程处于阻塞状态,如使用了sleep方法。
(2)使用while(!isInterrupted()){……}来判断线程是否被中断。
在第一种情况下使用interrupt方法,sleep方法将抛出一个InterruptedException例外,而在第二种情况下线程将直接退出。
public class Thread_Interruptextends Thread
{
public void run()
{
try
{
sleep(50000);// 延迟50秒
}
catch (InterruptedException e)
{
System.out.println(e.getMessage());
}
}
public static void main(String[] args)throws Exception
{
Thread thread =new Thread_Interrupt();
thread.start();
System.out.println("在50秒之内按任意键中断线程!");
System.in.read();
thread.interrupt();
thread.join();
System.out.println("线程已经退出!");
}
}
执行结果:
9、Java 实例 – 生产者/消费者问题:生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况:
存储空间已满,而生产者占用着它,消费者等着生产者让出空间从而去除产品,生产者等着消费者消费产品,从而向空间中添加产品。互相等待,从而发生死锁。
class Consumer extends Thread {
private CubbyHolecubbyhole;
private int number;
public Consumer(CubbyHole c,int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
int value =0;
for (int i =0; i <3; i++) {
value =cubbyhole.get();
System.out.println("消费者 #" +this.number+" got: " + value);
}
}
}
·······················································································
class Producer extends Thread {
private CubbyHolecubbyhole;
private int number;
public Producer(CubbyHole c,int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
for (int i =0; i <3; i++) {
cubbyhole.put(i);
System.out.println("生产者 #" +this.number +" put: " + i);
try {
sleep((int)(Math.random() *100));
}catch (InterruptedException e) { }
}
}
}
·······················································································
public class CubbyHole {
private int contents;
private boolean available =false;
public synchronized int get() {
while (available ==false) {
try {
wait();
}
catch (InterruptedException e) {
}
}
available =false;
notifyAll();
return contents;
}
public synchronized void put(int value) {
while (available ==true) {
try {
wait();
}
catch (InterruptedException e) {
}
}
contents = value;
available =true;
notifyAll();
}
}
·······················································································
public class P_C_Main {
public static void main(String[] args) {
CubbyHole c =new CubbyHole();
Producer p1 =new Producer(c,1);
Consumer c1 =new Consumer(c,1);
p1.start();
c1.start();
}
}
执行结果:
10、Java 实例 – 获取线程状态:
Java中的线程的生命周期大体可分为5种状态。
1. 新建状态(New):新创建了一个线程对象。
2. 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
3. 运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
4. 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
(一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
(三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
5. 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
执行结果:
11、Java 实例 – 获取所有线程:使用 getName() 方法获取所有正在运行的线程。
public class Thread_Getextends Thread{
public static void main(String[] args) {
Thread_Get t1 =new Thread_Get();
t1.setName("thread1");
t1.start();
ThreadGroup currentGroup =
Thread.currentThread().getThreadGroup();
int noThreads = currentGroup.activeCount();
Thread[] lstThreads =new Thread[noThreads];
currentGroup.enumerate(lstThreads);
for (int i =0; i < noThreads; i++)
System.out.println("线程号:" + i +" = " + lstThreads[i].getName());
}
}
执行结果:
12、Java 实例 – 查看线程优先级:使用 getThreadId() 方法获取线程id。
public class Thread_LookPrioities {
private static Runnable makeRunnable() {
Runnable r =new Runnable() {
public void run() {
for (int i =0; i <5; i++) {
Thread t = Thread.currentThread();
System.out.println("in run() - priority="
+ t.getPriority()+", name=" + t.getName());
try {
Thread.sleep(2000);
}
catch (InterruptedException x) {
}
}
}
};
return r;
}
public static void main(String[] args) {
System.out.println("in main() - Thread.currentThread().getPriority()=" + Thread.currentThread().getPriority());
System.out.println("in main() - Thread.currentThread().getName()="+ Thread.currentThread().getName());
Thread threadA =new Thread(makeRunnable(),"threadA");
threadA.start();
try {
Thread.sleep(3000);
}
catch (InterruptedException x) {
}
System.out.println("in main() - threadA.getPriority()="+ threadA.getPriority());
}
}
执行结果:
13、Java 实例 – 中断线程:使用interrupt()方法来中断线程并使用 isInterrupted() 方法来判断线程是否已中断。
public class Thread_InterruptStatusextends Object
implements Runnable{
public void run() {
try {
System.out.println("in run() - 将运行 work2() 方法");
work2();
System.out.println("in run() - 从 work2() 方法回来");
}
catch (InterruptedException x) {
System.out.println("in run() - 中断 work2() 方法");
return;
}
System.out.println("in run() - 休眠后执行");
System.out.println("in run() - 正常离开");
}
public void work2()throws InterruptedException {
while (true) {
if (Thread.currentThread().isInterrupted()) {
System.out.println("C isInterrupted()=" + Thread.currentThread().isInterrupted());
Thread.sleep(2000);
System.out.println("D isInterrupted()=" + Thread.currentThread().isInterrupted());
}
}
}
public void work()throws InterruptedException {
while (true) {
for (int i =0; i <100000; i++) {
int j = i *2;
}
System.out.println("A isInterrupted()=" + Thread.currentThread().isInterrupted());
if (Thread.interrupted()) {
System.out.println("B isInterrupted()=" + Thread.currentThread().isInterrupted());
throw new InterruptedException();
}
}
}
public static void main(String[] args) {
Thread_InterruptStatus si =new Thread_InterruptStatus();
Thread t =new Thread(si);
t.start();
try {
Thread.sleep(2000);
}
catch (InterruptedException x) {
}
System.out.println("in main() - 中断其他线程");
t.interrupt();
System.out.println("in main() - 离开");
}
}
执行结果: