线程组:(ThreadGroup)
把多个线程组合到一起,可以对一批线程进行分类管理,java允许程序直接对线程组进行控制。
默认情况下线程属于main的线程组,通过getThreadGroup().getName()方法可知。main线程也是属于名为main的线程组。
创建自己的线程组:
ThreadGroup tg = new ThreadGroup("我的线程组");
Thread t = new Thread(tg, myThread);
可以通过组名来设置同一个组的线程
例如:tg.SetDaemon(true);将组里所有线程设为守护线程
线程池:
当创建线程的时间和销毁线程的时间大于线程执行的时间时使用线程池。
为了节省时间和内容,将创建线程的时间在执行之前就全部完成。并且线程的数量固定,这样可以重用空闲线程。
线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。
Executors
JDK5新增了一个Executors工厂类来产生线程池,有如下几个方法
public static ExecutorService newCachedThreadPool()
public static ExecutorService newFixedThreadPool(int nThreads)
public static ExecutorService newSingleThreadExecutor()
这些方法的返回值是ExecutorService对象,该对象表示一个线程池,可以执行Runnable对象或者Callable对象代表的线程。它提供了如下方法
Future<> submit(Runnable task):执行线程任务
void shutdown() 关闭任务
public class TestExecutors {
public static void main(String[] args) {
//创建一个线程池
ExecutorService executor = Executors.newSingleThreadExecutor();
//2:将线程丢到线程池中。
executor.execute(new MyRunnable());
executor.execute(new MyRunnable());
executor.execute(new MyRunnable());
//关闭线程池
executor.shutdown();
/*ArrayBlockingQueue array = null;
array.add(e)*/
}
}
class MyRunnable extends Thread{
@Override
public void run() {
//输出一个语句。
System.out.println(Thread.currentThread().getName()+"执行了");
}
}
使用匿名内部类方法实现多线程:
//继承Thread类来实现
new Thread(){
public void run() {
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+"---"+i);
}
};
}.start();
//实现Runnable接口实现
new Thread(new Runnable(){
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+"---"+i);
}
}
}){}.start();
new Thread(new Runnable(){
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println("hello---"+i);
}
}
}){
public void run() {
for(int i=0;i<100;i++){
System.out.println("word---"+i);
}
}
}.start();
Lock类使用
可以用来替换synchronize,jdk5.0后出现
使用方法:
void lock()
获取锁
Condition newCondition()
返回绑定到此 Lock 实例的新 Condition 实例,该方法获取的Condition有await()等待,signal()唤醒等方法
void unlock()
释放锁
/*
* 包子,
* 篮子:6个包子。
* Lock类
* 线程的的总时间=线程的创建时间+线程的执行时间+线程的销毁时间。
* 5000个线程。
* 创建时间+销毁的时间》执行时间。
*
*/
public class HomeWork2 {
public static void main(String[] args) {
MyProduce2 pro1 = new MyProduce2();
pro1.setName("生产者1");
MyProduce2 pro2 = new MyProduce2();
pro2.setName("生产者2");
MyCustomer cus1 = new MyCustomer();
cus1.setName("消费者1");
MyCustomer cus2 = new MyCustomer();
cus2.setName("消费者2");
pro1.start();
pro2.start();
cus1.start();
cus2.start();
}
}
class Basket {
// 定义一个变量,
public static int index = 0;// 表示包子的编号。
public static final Lock lock = new ReentrantLock();
// 创建一个监视消费者的Condition
public static final Condition condi_pro = lock.newCondition();
public static final Condition condi_cus = lock.newCondition();
// 容器
public static final int SUM = 6;
// 集合用来装包子
public static List<MyBaozi> list = new ArrayList<MyBaozi>();
}
class MyBaozi {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public MyBaozi(int id) {
super();
this.id = id;
}
public MyBaozi() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "MyBaozi [id=" + id + "]";
}
}
class MyProduce2 extends Thread {
public void run() {
// 不断的生产包子。
while (true) {
// 先判断是否满了。满了就等待
// 获得锁
Basket.lock.lock();
while (Basket.list.size() >= Basket.SUM) {
// 等待
try {
Basket.condi_pro.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 否则就生产。
// 1;创建一个包子。
Basket.index++;
MyBaozi baozi = new MyBaozi(Basket.index);
// 2:将包子放到篮子里
Basket.list.add(baozi);
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "生产了"
+ baozi.getId() + "号包子,现有" + Basket.list.size() + "个");
// 唤醒等待中的线程。
Basket.condi_cus.signal();
Basket.lock.unlock();
}
}
}
class MyCustomer extends Thread {
@Override
public void run() {
while (true) {
Basket.lock.lock();
// 先要判断
while (Basket.list.size() == 0) {
try {
Basket.condi_cus.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 消费。从集合中取出一个包子。
MyBaozi baozi = Basket.list.remove(0);
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "消费了"
+ baozi.getId() + "号包子,现有" + Basket.list.size() + "个");
Basket.condi_pro.signal();
Basket.lock.unlock();
}
}
}