Java实例-线程

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() - 离开");

}

}

执行结果:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341

推荐阅读更多精彩内容

  • Java多线程学习 [-] 一扩展javalangThread类 二实现javalangRunnable接口 三T...
    影驰阅读 2,946评论 1 18
  • 本文主要讲了java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。 首先讲...
    李欣阳阅读 2,433评论 1 15
  • JUC 原创者:文思,感谢尚硅谷,资料来源于尚硅谷 目录: 1、volatile关键字与内存可见性 2、原子变量与...
    文思li阅读 2,264评论 0 1
  • 多线程概述 通过子类继承开启多线程public class Demo { public static voi...
    JerichoPH阅读 349评论 0 2
  • 小编费力收集:给你想要的面试集合 1.C++或Java中的异常处理机制的简单原理和应用。 当JAVA程序违反了JA...
    八爷君阅读 4,563评论 1 114