Java线程学习
2017-05-15 15:16
148 查看
一、创建线程的两种方式:
1、在Thread子类覆盖的run方法编写运行代码,在此处的run方法是属于Thread的子类,所以会优先执行。
Thread thread = new Thread(
@Override
public void run(){
//线程运行代码
}
);
2、在传递的Runnable对象中的run方法编写运行代码,Runnale里面的run方法是属于Thread父类的run方法,所以当子类中没有覆盖时才会执行。
Thread thread = new Thread(
new Runnable(){
@Override
public void run(){
//线程运行代码
}
}
);
总结:两者实现方式其实都是调用Thread对象里面的run方法,如果Thread对象里面的run方法没有被覆盖,并且为该对象设置了Runnable对象,则该run方法会调用Runnable对象的run方法。
二、定时器
格式:
Timer timer = new Timer();
timer.schedule( new TimerTask( 重写run方法),Date time//延迟时间,单位s);
三、线程间的互斥与通信
用synchronized关键字来互斥。
用wait和notify来通信。
用Java实现生产者消费者的几种方法:
1、采用synchronized锁以及wait notify方式实现
2、采用Lock锁以及await和signal方法是实现
3、采用BlockingQueue实现
扩展:
BlockingQueue有四个具体的实现类,根据不同需求,选择不同的实现类
1、ArrayBlockingQueue:一个由数组支持的有界阻塞队列,规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小.其所含的对象是以FIFO(先入先出)顺序排序的。
2、LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定.其所含的对象是以FIFO(先入先出)顺序排序的。
3、PriorityBlockingQueue:类似于LinkedBlockQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数的Comparator决定的顺序。
4、SynchronousQueue:特殊的BlockingQueue,对其的操作必须是放和取交替完成的。
LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的话,默认最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列空的时候会阻塞,直到有队列成员被放进来。
四、ThreadLocal实现线程范围内的共享变量
略
1、在Thread子类覆盖的run方法编写运行代码,在此处的run方法是属于Thread的子类,所以会优先执行。
Thread thread = new Thread(
@Override
public void run(){
//线程运行代码
}
);
2、在传递的Runnable对象中的run方法编写运行代码,Runnale里面的run方法是属于Thread父类的run方法,所以当子类中没有覆盖时才会执行。
Thread thread = new Thread(
new Runnable(){
@Override
public void run(){
//线程运行代码
}
}
);
总结:两者实现方式其实都是调用Thread对象里面的run方法,如果Thread对象里面的run方法没有被覆盖,并且为该对象设置了Runnable对象,则该run方法会调用Runnable对象的run方法。
二、定时器
格式:
Timer timer = new Timer();
timer.schedule( new TimerTask( 重写run方法),Date time//延迟时间,单位s);
三、线程间的互斥与通信
用synchronized关键字来互斥。
用wait和notify来通信。
用Java实现生产者消费者的几种方法:
1、采用synchronized锁以及wait notify方式实现
public class WaitAndNotify { public static void main(String[] args) throws IOException { Person person = new Person(); new Thread(new Consumer("消费者一", person)).start(); new Thread(new Consumer("消费者二", person)).start(); new Thread(new Consumer("消费者三", person)).start(); new Thread(new Producer("生产者一", person)).start(); new Thread(new Producer("生产者一", person)).start(); new Thread(new Producer("生产者一", person)).start(); } } class Producer implements Runnable { private Person person; private String producerName; public Producer(String producerName, Person person) { this.producerName = producerName; this.person = person; } @Override public void run() { while (true) { try { person.produce(); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Consumer implements Runnable { private Person person; private String consumerName; public Consumer(String consumerName, Person person) { this.consumerName = consumerName; this.person = person; } @Override public void run() { try { person.consume(); } catch (InterruptedException e) { e.printStackTrace(); } } } class Person { private int foodNum = 0; private Object synObj = new Object(); private final int MAX_NUM = 5; public void produce() throws InterruptedException { synchronized (synObj) { while (foodNum == 5) { System.out.println("box is full,size = " + foodNum); synObj.wait(); } foodNum++; System.out.println("produce success foodNum = " + foodNum); synObj.notifyAll(); } } public void consume() throws InterruptedException { synchronized (synObj) { while (foodNum == 0) { System.out.println("box is empty,size = " + foodNum); synObj.wait(); } foodNum--; System.out.println("consume success foodNum = " + foodNum); synObj.notifyAll(); } } }
2、采用Lock锁以及await和signal方法是实现
public class AwaitAndSignal { public static void main(String[] args) throws IOException { Person person = new Person(); new Thread(new Consumer(person), "消费者一").start(); new Thread(new Consumer(person), "消费者二").start(); new Thread(new Consumer(person), "消费者三").start(); new Thread(new Producer(person), "生产者一").start(); new Thread(new Producer(person), "生产者一").start(); new Thread(new Producer(person), "生产者一").start(); } } class Producer implements Runnable { private Person person; public Producer(Person person) { this.person = person; } @Override public void run() { for (int i = 0; i < 10; i++) { person.produce(); } } } class Consumer implements Runnable { private Person person; public Consumer(Person person) { this.person = person; } @Override public void run() { for (int i = 0; i < 10; i++) { person.consume(); } } } class Person { private int foodNum = 0; private ReentrantLock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); private final int MAX_NUM = 5; public void produce() { lock.lock(); try { while (foodNum == MAX_NUM) { System.out.println("box is full,size = " + foodNum); condition.await(); } foodNum++; System.out.println("produce success foodNum = " + foodNum); condition.signalAll(); } catch(InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public void consume() { lock.lock(); try { while (foodNum == 0) { System.out.println("box is empty,size = " + foodNum); condition.await(); } foodNum--; System.out.println("consume success foodNum = " + foodNum); condition.signalAll(); } catch(InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } }
3、采用BlockingQueue实现
public class Producer implements Runnable { BlockingQueue<String> queue; public Producer(BlockingQueue<String> queue) { this.queue = queue; } @Override public void run() { try { String temp = "A Product, 生产线程:" + Thread.currentThread().getName(); System.out.println("I have made a product:" + Thread.currentThread().getName()); queue.put(temp);//如果队列是满的话,会阻塞当前线程 } catch (InterruptedException e) { e.printStackTrace(); } } } import java.util.concurrent.BlockingQueue; public class Consumer implements Runnable{ BlockingQueue<String> queue; public Consumer(BlockingQueue<String> queue){ this.queue = queue; } @Override public void run() { try { String temp = queue.take();//如果队列为空,会阻塞当前线程 System.out.println(temp); } catch (InterruptedException e) { 9d2a e.printStackTrace(); } } } import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; public class Test3 { public static void main(String[] args) { BlockingQueue<String> queue = new LinkedBlockingQueue<String>(2); // BlockingQueue<String> queue = new LinkedBlockingQueue<String>(); //不设置的话,LinkedBlockingQueue默认大小为Integer.MAX_VALUE // BlockingQueue<String> queue = new ArrayBlockingQueue<String>(2); Consumer consumer = new Consumer(queue); Producer producer = new Producer(queue); for (int i = 0; i < 5; i++) { new Thread(producer, "Producer" + (i + 1)).start(); new Thread(consumer, "Consumer" + (i + 1)).start(); } } }
扩展:
BlockingQueue有四个具体的实现类,根据不同需求,选择不同的实现类
1、ArrayBlockingQueue:一个由数组支持的有界阻塞队列,规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小.其所含的对象是以FIFO(先入先出)顺序排序的。
2、LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定.其所含的对象是以FIFO(先入先出)顺序排序的。
3、PriorityBlockingQueue:类似于LinkedBlockQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数的Comparator决定的顺序。
4、SynchronousQueue:特殊的BlockingQueue,对其的操作必须是放和取交替完成的。
LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的话,默认最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列空的时候会阻塞,直到有队列成员被放进来。
四、ThreadLocal实现线程范围内的共享变量
略
相关文章推荐
- java线程学习基础
- Java线程学习和总结
- java多线程学习五:线程间的通信
- 关于java 线程学习
- java学习之进程和线程
- java学习日记(线程)
- Java多线程学习 (一) 前台、后台线程
- java多线程学习三:联合线程
- 今天学习了JAVA程序、线程、进程的区别
- java Thread类 线程学习 一:
- java线程初步学习
- Java线程学习和总结
- java 线程学习(一)
- Java线程学习
- Java线程学习11.30
- Java 学习笔记 (5) - 线程 Thread
- Java线程学习和总结
- JAVA学习【知】线程
- Java基础学习笔记(十)线程的创建总结
- java Thread类 线程学习 一: