一丶两个线程交替打印1~100的数
注意:当一个线程进入了同步代码块的时候,就应该释放另一个线程,当线程完成了一次的打印以后,应该自我wait(), 这样就可以做到两个线程交替打印:1~100
package com.iflysse.test03;
public class Day032901 {
public static void main(String[] args) {
MyTest m = new MyTest();
Thread t1 = new Thread(m);
Thread t2 = new Thread(m);
t1.start();
t2.start();
}
}
class MyTest implements Runnable{
//两个线程交替打印1-100的数,使用wait()/notify()
@SuppressWarnings("static-access")
@Override
public void run() {
for(int i = 0;i < 100; i++){
synchronized (this) {
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.notifyAll();
System.out.println(Thread.currentThread().getName() + " :" + i);
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
二丶两个线程打印奇数、偶数
package com.iflysse.test03;
//利用多线程打印奇数,偶数
public class Day032801 {
public static void main(String[] args) {
MyThread m1 = new MyThread();
MyThread1 m2 = new MyThread1();
m1.start();
m2.start();
}
}
class MyThread extends Thread{
@Override
public void run() {
for(int i = 0;i<100;i++){
if(i%2 ==1){
System.out.println("奇数线程:"+i);
}
}
}
}
class MyThread1 extends Thread{
@Override
public void run() {
for(int i = 0;i<100;i++){
if(i%2 ==0){
System.out.println("偶数线程:"+i);
}
}
}
}
三丶线程的死锁
注意:要理解两个线程抢占cpu资源之后,睡眠,当线程唤醒的时候,另一个资源被另一个线程所持有,两个线程谁也不愿意放开资源,导致了死锁
package com.iflysse.test03;
public class Day032902 {
public static void main(String[] args) {
StringBuffer sb1 = new StringBuffer();
StringBuffer sb2 = new StringBuffer();
//定义两个线程 1 2
//A先获取锁sb1 插入数据 再获取所sb2 打印数据
//B先获取所sb2 再获取所sb1
//定义线程1
//匿名类匿名对象 1
new Thread(){
@SuppressWarnings("static-access")
public void run(){
synchronized (sb1) {
sb1.append("A");
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (sb2) {
sb2.append("B");
System.out.println("=========================");
System.out.println(sb1);
System.out.println(sb2);
System.out.println("=========================");
}
}
}
}.start();
new Thread(){
@SuppressWarnings("static-access")
public void run(){
synchronized (sb2) {
sb2.append("C");
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (sb1) {
sb1.append("D");
System.out.println("******************************");
System.out.println(sb1);
System.out.println(sb2);
System.out.println("******************************");
}
}
}
}.start();
}
}
四丶多线程的生产者、消费者模式
生产者 消费者
现有一个空仓库,此仓库的最大的存储量是100吨,有5个生产者,每次可以生产30,、40、50、60、70吨,有5个消费者,每次可以消费10、20、30、40、50吨,每次生产者生产的货物放入仓库之前都会有一次判断,判断当前的空余量能否装下此次的生产量。如果能装下就装入仓库,如果装不下就排队等待……可以定义一个仓库类,一个仓库里面可以有“入库”和“出库”方法。其实每次生产和消费就可以理解成多个线程,分别对应仓库的入库和出库,这里还要涉及到线程安全问题。直到生产者或消费者全部运行完毕,或者仓库不能满足任何线程运行,程序会停留在那里……
注意:这里应该有4个类:仓库类,生产者类,消费者类,测试类
package com.iflysse.test03;
import java.util.*;
public class Storage {
private static final int MAX = 100; //最大库存量
private List<Object> lst = new ArrayList<>(MAX);//库存余量
public void put(int num){
synchronized (lst) {
while (MAX - lst.size() < num) {
System.out.println(String.format(
"当前库存空余量为:%d,此次生产量为:%d,库存余量 不足" + " 请等待。。。。",
MAX - lst.size(), num));
try {
lst.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(String.format("当前库存空余量为: %d,此次"
+ "生产量为:%d,产品正在入库请等待。。。", MAX - lst.size(),num));
for(int i = 0; i< num;i++){
lst.add(new Object());
}
System.out.println("入库操作完毕!");
lst.notifyAll();
}
}
public void get(int num){
synchronized (lst) {
while (lst.size() < num) {
System.out.println(String.format("当前库存量余量为:%d,销售量为:%d,库存余量不足,请等待。。。。\n",lst.size(), num));
try {
lst.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.printf(String.format("当前库存余量为:%d,销售量为:%d\n",lst.size(),num));
for(int i = 0; i < num; i++){
lst.remove(0);
}
System.out.println("出库操作完毕!");
lst.notifyAll();
}
}
public int getMax(){
return MAX;
}
public int getNum(){
return lst.size();
}
}
package com.iflysse.test03;
public class Producter extends Thread {
private int num;
private Storage storage;
public Producter(int num,Storage storage){
this.num = num;
this.storage = storage;
}
public void run(){
this.produce();
}
public void produce(){
this.storage.put(num);
}
}
package com.iflysse.test03;
public class Consumer extends Thread{
private int num;
private Storage storage;
public Consumer(int num, Storage storage) {
super();
this.num = num;
this.storage = storage;
}
public void run(){
this.consum();
}
public void consum(){
this.storage.get(this.num);
}
}
package com.iflysse.test03;
public class Main {
@SuppressWarnings("static-access")
public static void main(String[] args) {
Storage storage = new Storage();
Thread[] threads ={
new Producter(30, storage),
new Producter(40, storage),
new Producter(50, storage),
new Producter(60, storage),
new Producter(70, storage),
new Consumer(10, storage),
new Consumer(20, storage),
new Consumer(30, storage),
new Consumer(40, storage),
new Consumer(50, storage),
};
System.out.printf("仓库容量为:%d\n",storage.getMax());
for(Thread ele: threads){
ele.start();
}
try {
Thread.currentThread().sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.printf("仓库库存量为:%d\n",storage.getNum());
}
}