首页 > 编程语言 > 详细

多线程补充

时间:2017-03-24 00:12:32      阅读:248      评论:0      收藏:0      [点我收藏+]

1、线程的状态

线程对象在不同的运行时期有不同的状态,状态信息就存在于State枚举类中

Thread.State :

NEW :至今尚未启动的线程

RUNNABLE:正在java虚拟机中执行的线程

BLOCKED:受阻塞于并等待某个监视器锁的线程

WAITING:无限期的等待另一个线程来执行某一个特定操作的线程

TIMED_WAITING:等待另一个线程来执行某一特定操作的线程

TERMINATED:已退出的线程

 技术分享

package com.threadTest.thread.add.state.test01;

/**
 * Created by sky on 2017/3/23.
 */
public class Run {
    public static void main(String[] args) {
        try {
            MyThread thread01 = new MyThread();
            System.out.println("main 方法中的状态1: " + thread01.getState());
            Thread.sleep(1000);
            thread01.start();
            Thread.sleep(1000);
            System.out.println("main 方法中的状态2: " + thread01.getState());
            MyThread thread02 = new MyThread();
            System.out.println("main 方法中的状态1: " + thread02.getState());
            Thread.sleep(1000);
            thread02.start();
            Thread.sleep(1000);
            System.out.println("main 方法中的状态2: " + thread02.getState());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

输出:
构造方法中的状态1: RUNNABLE
构造方法中的状态2: RUNNABLE
main 方法中的状态1: NEW
run 构造方法中的状态1: RUNNABLE
main 方法中的状态2: TIMED_WAITING
构造方法中的状态1: RUNNABLE
构造方法中的状态2: RUNNABLE
main 方法中的状态1: NEW
run 构造方法中的状态1: RUNNABLE
main 方法中的状态2: TIMED_WAITING
package com.threadTest.thread.add.state.test01;

/**
 * Created by sky on 2017/3/23.
 */
public class Lock {
    public static final Byte lock = new Byte("0");
}
package com.threadTest.thread.add.state.test01;


/**
 * Created by sky on 2017/3/23.
 */
public class MyThread extends Thread {
    public MyThread() {
        try {
            System.out.println("构造方法中的状态1: " + Thread.currentThread().getState());
            Thread.sleep(1000);
            System.out.println("构造方法中的状态2: " + Thread.currentThread().getState());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        try {
            System.out.println("run 构造方法中的状态1: " + Thread.currentThread().getState());
            Thread.sleep(1000);
            try {
                synchronized (Lock.lock) {
                    Thread.sleep(1000);
                    Lock.lock.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("run 构造方法中的状态2: " + Thread.currentThread().getState());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

2、线程组

线程组作用:可以批量的管理线程或线程组对象,有效地对线程或线程组对象进行组织。

技术分享

 

1)线程对象关联线程组:1级关联

1级关联:父对象中有子对象,但并不创建子孙对象。为了有效地对这些线程进行组织管理,通常情况下是创建一个线程组,然后将部分线程归属到该组中,对零散的线程进行有限的组织与规划。

package com.threadTest.thread.add.state.group;

/**
 * Created by sky on 2017/3/23.
 */
public class ThreadA extends Thread{
    @Override
    public void run() {
        try
        {
            while (!Thread.currentThread().isInterrupted())
            {
                System.out.println("ThreadName = " + Thread.currentThread().getName());
                Thread.sleep(3000);
            }
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}
package com.threadTest.thread.add.state.group;

/**
 * Created by sky on 2017/3/23.
 */
public class ThreadB extends Thread{
    @Override
    public void run() {
        try
        {
            while (!Thread.currentThread().isInterrupted())
            {
                System.out.println("ThreadName = " + Thread.currentThread().getName());
                Thread.sleep(3000);
            }
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}
package com.threadTest.thread.add.state.group;

/**
 * Created by sky on 2017/3/23.
 */
public class Run {
    public static void main(String[] args) {
        ThreadA threadA = new ThreadA();
        ThreadB threadB = new ThreadB();
        ThreadGroup group = new ThreadGroup("线程组");
        Thread athread = new Thread(group, threadA);
        Thread bthread = new Thread(group, threadB);
        athread.start();
        bthread.start();
        System.out.println("interrupt前活动的线程组: " + group.activeCount());
        System.out.println("线程组的名称为: " + group.getName());
        //线程中断
        group.interrupt();
        System.out.println("interrupt后活动的线程组: " + group.activeCount());
        group.list();
    }
}
输出:
interrupt前活动的线程组: 2
线程组的名称为: 线程组
interrupt后活动的线程组: 2
java.lang.ThreadGroup[name=线程组,maxpri=10]
    Thread[Thread-2,5,线程组]
    Thread[Thread-3,5,线程组]

2)线程对象关联线程组:多级关联

多级关联:父对象中有子对象,子对象中再创建子对象

package com.threadTest.thread.add.state.group.test02;

/**
 * Created by sky on 2017/3/23.
 */
public class Run {
    public static void main(String[] args) {
        //在main组中添加一个线程组A,然后在这个A中添加线程对象Z
        //方法acctiveGroupCount()个acctiveCount()的值不是固定的
        //是系统环境的一个快照
        ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
        ThreadGroup group = new ThreadGroup(mainGroup, "A");
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("runMethod!");
                try {
                    Thread.sleep(10000); //线程必须在运行状态下才可以受组管理
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Thread newThread = new Thread(group, runnable);
        newThread.setName("Z");
        newThread.start();//线程必须启动后才归到A组中
        ThreadGroup[] listGroup = new ThreadGroup[Thread.currentThread().getThreadGroup().activeGroupCount()];
        Thread.currentThread().getThreadGroup().enumerate(listGroup);
        System.out.println("main 线程中有多少个子线程组: " + listGroup.length + " 名字为: " + listGroup[0].getName());;
        Thread[] listThread = new Thread[listGroup[0].activeCount()];
        //将此listGroup[0]线程组中的每个活动线程复制到指定的数组中listThread
        listGroup[0].enumerate(listThread);
        System.out.println(listThread[0].getName());
    }
}

3)线程组自动归属特性

自动归属:自动归到当前线程组中

package com.threadTest.thread.add.state.group.test03;


/**
 * Created by sky on 2017/3/23.
 */
public class Run {
    public static void main(String[] args) {
        //方法activeGroupCount()取得当前线程组对象中的子线程数量
        //方法acctiveGroupCount()的作用是将线程中的子线程组以复制的形式拷贝到ThreadGroup[]数组对象中
        System.out.println("A处线程:" + Thread.currentThread().getName()
                + "所属的线程组名为:"
                + Thread.currentThread().getThreadGroup().getName() + " "
                + "中有线程组数量: "
                + Thread.currentThread().getThreadGroup().activeGroupCount());
        ThreadGroup group = new ThreadGroup("新的组");//自动加到main组中
        System.out.println("B处线程:" + Thread.currentThread().getName()
                + " 所属的线程组名为: "
                + Thread.currentThread().getThreadGroup().getName()
                + " 中有线程组数量"
                + Thread.currentThread().getThreadGroup().activeGroupCount());
        ThreadGroup[] threadGroups = new ThreadGroup[Thread.currentThread().getThreadGroup().activeGroupCount()];
        Thread.currentThread().getThreadGroup().enumerate(threadGroups);
        for (int i = 0; i < threadGroups.length; i++) {
            System.out.println("第一个线程组名称为: " + threadGroups[i].getName());
        }
    }
}

输出:
A处线程:main所属的线程组名为:main 中有线程组数量: 0
B处线程:main 所属的线程组名为: main 中有线程组数量1
第一个线程组名称为: 新的组

 4)获取根线程组

package com.threadTest.thread.add.state.group.test04;

/**
 * Created by sky on 2017/3/23.
 */
public class Run {
    public static void main(String[] args) {
        System.out.println("线程:" + Thread.currentThread().getName()
        + " 所在的线程组名为: "
        + Thread.currentThread().getThreadGroup().getName());
        System.out.println("main线程所在的线程组的父线程组名称是:"
        +Thread.currentThread().getThreadGroup().getParent()
                .getName());
        System.out.println("main线程所在的线程组的父线程组的父线程组的名称是:"
        +Thread.currentThread().getThreadGroup().getParent()
        .getParent().getName());
    }
}

输出:
Exception in thread "main" java.lang.NullPointerException
    at com.threadTest.thread.add.state.group.test04.Run.main(Run.java:16)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
线程:main 所在的线程组名为: main
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
main线程所在的线程组的父线程组名称是:system
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

5)线程组里加线程组

package com.threadTest.thread.add.state.group.test05;

/**
 * Created by sky on 2017/3/23.
 */
public class Run {
    public static void main(String[] args) {
        System.out.println("线程组名称:"
                + Thread.currentThread().getThreadGroup().getName());
        System.out.println("线程组中活动的线程数量:"
                + Thread.currentThread().getThreadGroup().activeCount());
        System.out.println("线程组中线程组的数量-加之前:"
                + Thread.currentThread().getThreadGroup().activeGroupCount());
        new ThreadGroup(Thread.currentThread().getThreadGroup(), "newGroup");
        System.out.println("线程组中线程组数量-加之后:"
                + Thread.currentThread().getThreadGroup().activeGroupCount());
        System.out.println("父线程组名称:"
                + Thread.currentThread().getThreadGroup().getParent().getName());
    }
}

输出:
线程组名称:main
线程组中活动的线程数量:2
线程组中线程组的数量-加之前:0
线程组中线程组数量-加之后:1
父线程组名称:system

6)组内的线程的批量停止

package com.threadTest.thread.add.state.group.test06;

/**
 * Created by sky on 2017/3/23.
 */
public class MyThread extends Thread{
    public MyThread(ThreadGroup group, String name){
        super(group, name);
    }
    @Override
    public void run() {
        System.out.println("ThreadName=" + Thread.currentThread()
                .getName() + "准备开始死循环了:)");
        while (!this.isInterrupted()) {
        }
        System.out.println("ThreadName=" + Thread.currentThread().getName()
        +"结束了:)");
    }
}
package com.threadTest.thread.add.state.group.test06;

/**
 * Created by sky on 2017/3/23.
 */
public class Run {
    public static void main(String[] args) {
        try {
            ThreadGroup group = new ThreadGroup("我的线程组");
            for (int i = 0; i < 5; i++) {
                MyThread thread = new MyThread(group, "线程" + (i + 1));
                thread.start();
            }
            Thread.sleep(5000);
            group.interrupt();
            System.out.println("调用了interrupt()方法");
        } catch (InterruptedException e) {
            System.out.println("停了!");
            e.printStackTrace();
        }
    }
}
输出:
ThreadName=线程1准备开始死循环了:)
ThreadName=线程2准备开始死循环了:)
ThreadName=线程3准备开始死循环了:)
ThreadName=线程4准备开始死循环了:)
ThreadName=线程5准备开始死循环了:)
调用了interrupt()方法
ThreadName=线程1结束了:)
ThreadName=线程5结束了:)
ThreadName=线程4结束了:)
ThreadName=线程3结束了:)
ThreadName=线程2结束了:)

7)递归与非递归取得组内对象

package com.threadTest.thread.add.state.group.test07;

import com.threadTest.thread.add.state.group.test06.MyThread;

/**
 * Created by sky on 2017/3/23.
 */
public class Run {
    public static void main(String[] args) {
        ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
        ThreadGroup groupA = new ThreadGroup(mainGroup, "A");
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("runMethod!");
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        ThreadGroup groupB = new ThreadGroup(groupA, "B");
        //分配空间,但不一定全部用完
        ThreadGroup[] listGroup1 = new ThreadGroup[Thread.currentThread().getThreadGroup().activeGroupCount()];
        //传入true是递归取得子组及子孙组
        Thread.currentThread().getThreadGroup().enumerate(listGroup1,true);
        for (int i = 0; i < listGroup1.length; i++) {
            if (null != listGroup1[i]) {
                System.out.println(listGroup1[i].getName());
            }
        }
        ThreadGroup[] listGroup2 = new ThreadGroup[Thread.currentThread().getThreadGroup().activeGroupCount()];
        //传入true是递归取得子组及子孙组
        Thread.currentThread().getThreadGroup().enumerate(listGroup2,false);
        for (int i = 0; i < listGroup2.length; i++) {
            if (null != listGroup2[i]) {
                System.out.println(listGroup2[i].getName());
            }
        }
    }
}

输出:
A
B
A

 

多线程补充

原文:http://www.cnblogs.com/beaconSky/p/6606425.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!