1 两个线程交替打印自然数
方法0
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Demo {
public static void main(String[] args) {
Object obj = new Object();
Thread thread1 = new Thread(new PrintNum(obj, true), "thread1");
Thread thread2 = new Thread(new PrintNum(obj, false), "thread2");
//Thread thread3 = new Thread(new PrintNum(obj, false), "thread3");
thread2.start();
//thread3.start();
thread1.start();
}
}
class PrintNum implements Runnable{
private static int num;
private Object obj;
private boolean isFirstThread;
public PrintNum(Object obj, boolean isFirstThread) {
num = 0;
this.obj = obj;
this.isFirstThread = isFirstThread;
}
@Override
public void run() {
synchronized (obj) {
while (true) {
// 第一次进来可以直接打印,但是第二次进来后要等到被被唤醒才能打印
if (isFirstThread) {
isFirstThread = false;
} else {
try {
obj.wait();
TimeUnit.SECONDS.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + ": " + num++);
// 通知其他线程
obj.notifyAll();
}
}
}
}
方法1:
package com.lzg.flume.intercepter.thread.test21;
public class Test {
public static void main(String[] args) {
Object o = new Object();
Thread thread1 = new Thread(new PrintNum(o), "thread1");
Thread thread2 = new Thread(new PrintNum(o), "thread2");
thread1.start();
thread2.start();
}
}
class PrintNum implements Runnable {
private static int num;//注意必须用静态变量,静态变量只会在类加载时初始化一次。
//静态成员属于整个类,当系统第一次使用该类时,就会为其分配内存空间直到该类被卸载才会进行资源回收!~~
//程序运行时静态初始化块最先被执行,然后执行普通初始化块,最后才执行构造方法。由于静态初始化块只在类加载时执行一次,所以当再次创建对象 hello2 时并未执行静态初始化块。
private Object lock;
public PrintNum(Object obj) {
num = 0;
this.lock = obj;
}
@Override
public void run() {
synchronized (lock) {
while (true) {
lock.notify();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " Thread Print: " + num++);
}
}
}
}
2 写一个producer consumer
package com.lzg.flume.intercepter.thread.test11;
public class ProCons {
public static void main(String[] args) {
QueueBuffer q = new QueueBuffer();
new Thread(new Producer(q), "Producer").start();
new Thread(new Consumer(q), "Consumer").start();
System.out.println("Press Control-C to stop.");
}
}
class QueueBuffer {
int n;
boolean valueSet = false;
synchronized int get() {
if (!valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
System.out.println("Got: " + n);
valueSet = false;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
notify();
return n;
}
synchronized void put(int n) {
if (valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n = n;
System.out.println("Put: " + n);
valueSet = true;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
notify();
}
}
class Consumer implements Runnable {
private QueueBuffer q;
Consumer(QueueBuffer q) {
this.q = q;
}
public void run() {
while (true) {
q.get();
}
}
}
class Producer implements Runnable {
private QueueBuffer q;
Producer(QueueBuffer q) {
this.q = q;
}
public void run() {
int i = 0;
while (true) {
q.put(i++);
}
}
}
3 现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行?
public static void main(String[] args) {
method01();
method02();
}
/**
* 第一种实现方式,顺序写死在线程代码的内部了,有时候不方便
*/
private static void method01() {
Thread t1 = new Thread(new Runnable() {
@Override public void run() {
System.out.println("t1 is finished");
}
});
Thread t2 = new Thread(new Runnable() {
@Override public void run() {
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t2 is finished");
}
});
Thread t3 = new Thread(new Runnable() {
@Override public void run() {
try {
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t3 is finished");
}
});
t3.start();
t2.start();
t1.start();
}
/**
* 第二种实现方式,线程执行顺序可以在方法中调换
*/
private static void method02(){
Runnable runnable = new Runnable() {
@Override public void run() {
System.out.println(Thread.currentThread().getName() + "执行完成");
}
};
Thread t1 = new Thread(runnable, "t1");
Thread t2 = new Thread(runnable, "t2");
Thread t3 = new Thread(runnable, "t3");
try {
t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
t3.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
方法2 用reentrantlock的condition来实现
package com.lzg.flume.intercepter.thread1.test1.test3;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionService {
private int signal = 1;
private ReentrantLock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
public void excuteA(){
try {
lock.lock();
while(signal!=1){
conditionA.await();
}
System.out.println(Thread.currentThread().getName() + " 工作");
signal = 2;
conditionB.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void excuteB(){
try {
lock.lock();
while(signal!=2){
conditionB.await();
}
System.out.println(Thread.currentThread().getName() + " 工作");
signal = 3;
conditionC.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void excuteC(){
try {
lock.lock();
while(signal!=3){
conditionC.await();
}
System.out.println(Thread.currentThread().getName() + " 工作");
signal = 1;
conditionA.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.lzg.flume.intercepter.thread1.test1.test3;
/**
* 线程按顺序执行
* @author lixiaoxi
*
*/
public class ConditionApplication1 {
private static Runnable getThreadA(final ConditionService service) {
return new Runnable() {
@Override
public void run() {
for (int i=0;i<10;i++) {
service.excuteA();
}
}
};
}
private static Runnable getThreadB(final ConditionService service) {
return new Runnable() {
@Override
public void run() {
for (int i=0;i<10;i++) {
service.excuteB();
}
}
};
}
private static Runnable getThreadC(final ConditionService service) {
return new Runnable() {
@Override
public void run() {
for (int i=0;i<10;i++) {
service.excuteC();
}
}
};
}
public static void main(String[] args) throws InterruptedException{
ConditionService service = new ConditionService();
Runnable A = getThreadA(service);
Runnable B = getThreadB(service);
Runnable C = getThreadC(service);
new Thread(A, "A").start();
new Thread(B, "B").start();
new Thread(C, "C").start();
}
}
3 自己写一个blockQueue
package com.lzg.flume.intercepter.thread1.test1.test2;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
public class MyBlockQueue<E> {
private final List list;
private final int limit;
public MyBlockQueue(int limit) {
this.limit = limit;
list = new LinkedList<E>();
}
public synchronized void put(E e) {
while (list.size() == limit) {
try {
this.wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " list: " + list.toString());
System.out.println(Thread.currentThread().getName() + " put: " + e);
list.add(e);
this.notifyAll();
}
public synchronized E get() {
while (list.size() == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " list: " + list.toString());
E remove = (E) list.remove(0);
System.out.println(Thread.currentThread().getName() + " get: " + remove);
notifyAll();
return remove;
}
}
class Producer<E> implements Runnable {
private final MyBlockQueue queue;
public Producer(MyBlockQueue<E> queue) {
this.queue = queue;
}
@Override
public void run() {
while (true) {
Random random = new Random();
int r = random.nextInt(40);
queue.put(r);
}
}
}
class Consumer<E> implements Runnable {
private final MyBlockQueue queue;
public Consumer(MyBlockQueue<E> queue) {
this.queue = queue;
}
@Override
public void run() {
while (true) {
queue.get();
}
}
}
package com.lzg.flume.intercepter.thread1.test1.test2;
import java.util.LinkedList;
import java.util.Random;
public class TestMain {
public static void main(String[] args) {
MyBlockQueue<Integer> integerMyBlockQueue = new MyBlockQueue<Integer>(2);
Producer<Integer> producer = new Producer<Integer>(integerMyBlockQueue);
Consumer<Integer> consumer = new Consumer<Integer>(integerMyBlockQueue);
Thread thread1 = new Thread(producer);
Thread thread2 = new Thread(consumer);
thread1.start();
thread2.start();
}
}
方法2 juc的方式来实现
package com.lzg.flume.intercepter.thread1.test1.test2;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyBlockQueue1<E> {
private final List list;
private final int limit;//有大小限制的
private final Lock lock = new ReentrantLock();
private final Condition notFull = lock.newCondition();
private final Condition notEmpty = lock.newCondition();
public MyBlockQueue1(int limit) {
this.limit = limit;
this.list = new LinkedList<E>();
}
public void put(E e) throws InterruptedException {
lock.lock();
try {
while (list.size() == limit){
notFull.await();
}
System.out.println(Thread.currentThread().getName() + " list: " + list.toString());
System.out.println(Thread.currentThread().getName() + " put: " + e);
list.add(e);
notEmpty.signalAll();
}finally {
lock.unlock();
}
}
public E get() throws InterruptedException {
lock.lock();
try {
while (list.size() == 0){
notEmpty.await();
}
System.out.println(Thread.currentThread().getName() + " list: " + list.toString());
E remove = (E) list.remove(0);
System.out.println(Thread.currentThread().getName() + " get: " + remove);
notFull.signalAll();
return remove;
}finally {
lock.unlock();
}
}
}
class Producer1<E> implements Runnable {
private final MyBlockQueue1 queue;
public Producer1(MyBlockQueue1<E> queue) {
this.queue = queue;
}
@Override
public void run() {
while (true) {
Random random = new Random();
int r = random.nextInt(40);
try {
queue.put(r);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer1<E> implements Runnable {
private final MyBlockQueue1 queue;
public Consumer1(MyBlockQueue1<E> queue) {
this.queue = queue;
}
@Override
public void run() {
while (true) {
try {
queue.get();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}