1、生产者-消费者模型:
public class ProducerConsumer {
public static void main(String[] args) {
SyncStack ss = new SyncStack();
Producer p = new Producer(ss);
Consumer c = new Consumer(ss);
new Thread(p).start();
new Thread(p).start();
new Thread(c).start();
new Thread(c).start();
}
}
class WoTou {
int id;
WoTou(int id) {
this.id = id;
}
public String toString() {
return "WoTou : " + id;
}
}
class SyncStack {
int index = 0;
WoTou[] arrWT = new WoTou[6];
public synchronized void push(WoTou wt) {
while(index == arrWT.length) {
try {
//拿到对象锁的线程wait
//一旦wait就释放对象锁
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();//叫醒之前wait的线程
arrWT[index] = wt;
index ++;
}
public synchronized WoTou pop() {
//不能用if,用if如果有catch,会跳出if向下执行就出问题
//用while他会继续判断
while(index == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
index--;
return arrWT[index];
}
}
class Producer implements Runnable {
SyncStack ss = null;
Producer(SyncStack ss) {
this.ss = ss;
}
public void run() {
for(int i=0; i<20; i++) {
WoTou wt = new WoTou(i);
ss.push(wt);
System.out.println("生产了" + wt);
try {
Thread.sleep((int)(Math.random() * 200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable {
SyncStack ss = null;
Consumer(SyncStack ss) {
this.ss = ss;
}
public void run() {
for(int i=0; i<20; i++) {
WoTou wt = ss.pop();
System.out.println("消费了: " + wt);
try {
Thread.sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2、线程交替执行:
一个打印1-100的奇数,一个打印1-100的偶数;要求:线程1打印5个之后,线程2开始打印,线程2打印5个之后,线程1再开始打印,以此循环。
package threadtest;
public class Test1 {
/*
* 两个线程,一个打印1-100的奇数,一个打印1-100的偶数;要求:线程1打印5个之后,线程2开始打印,线程2打印5个之后,线程1再开始打印,以此循环。
*/
private static int state = 1;
private static int num1 = 1;
private static int num2 = 2;
public static void main(String[] args) {
// TODO Auto-generated method stub
final Test1 t = new Test1();
new Thread(new Runnable(){
@Override
public void run(){
while(num1<100){
//两个线程都用t对象作为锁,保证每个交替期间只有一个线程在打印
synchronized(t){
// 如果state!=1, 说明此时尚未轮到线程1打印, 线程1将调用t的wait()方法, 直到下次被唤醒
if(state!=1){
try{
t.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
// 当state=1时, 轮到线程1打印5次数字
for(int j=0;j<5;j++){
System.out.println(num1);
num1 +=2;
}
// 线程1打印完成后, 将state赋值为2, 表示接下来将轮到线程2打印
state = 2;
// notifyAll()方法唤醒在t上wait的线程2, 同时线程1将退出同步代码块, 释放t锁
t.notifyAll();
}
}
}
}).start();
new Thread(new Runnable(){
@Override
public void run(){
while(num2<100){
synchronized(t){
if(state!=2){
try{
t.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
for(int i=0;i<5;i++){
System.out.println(num2);
num2 +=2;
}
state=1;
t.notifyAll();
}
}
}
}).start();
}
}
3、线程顺序执行
public class JoinTest2 {
// 1.现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行
public static void main(String[] args) {
final Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("t1");
}
});
final Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
//引用t1线程,等待t1线程执行完
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t2");
}
});
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
try {
//引用t2线程,等待t2线程执行完
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t3");
}
});
t3.start();
t2.start();
t1.start();
}
}