代码示例:
多线程实现
洗衣服类线程
package com.lanou3g.p04;
public class WashClothes implements Runnable{
@Override
public void run() {
int i = 0;
while(i < 5) {
SleepTimes.sleep();
System.out.println("洗衣中......");
i++;
}
}
}
等待一分钟类
package com.lanou3g.p04;
public class SleepTimes {
public static void sleep() {
long timeMillis = System.currentTimeMillis();
while((System.currentTimeMillis() - timeMillis) < 1000) {
}
}
}
脱地类线程
package com.lanou3g.p04;
public class CleanFloor implements Runnable{
@Override
public void run() {
for(int i = 0; i < 12; i++) {
SleepTimes.sleep();
System.out.println("扫地中.......");
}
}
}
晒衣服类线程
package com.lanou3g.p04;
public class SunClothes implements Runnable{
@Override
public void run() {
SleepTimes.sleep();
for(int i = 0; i < 2; i++) {
System.out.println("晒衣服中......");
}
}
}
保姆类
package com.lanou3g.p04;
public class BM implements Runnable{
public boolean flag = false;
@Override
public void run() {
WashClothes wClothes = new WashClothes();
Thread tw = new Thread(wClothes);
System.out.println("开始洗衣服");
tw.start();
CleanFloor cFloor = new CleanFloor();
Thread cf = new Thread(cFloor);
cf.start();
try {
tw.join();
cf.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("地拖完了");
SunClothes sunClothes = new SunClothes();
Thread sc = new Thread(sunClothes);
sc.start();
try {
sc.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
BM bm = new BM();
Dun dun = new Dun(bm);
Qi qi = new Qi(bm);
Thread t1 = new Thread(dun);
Thread t2 = new Thread(qi);
t1.start();
t2.start();
}
}
class Dun implements Runnable{
private int num = 0;
private BM bm;
public Dun() {}
public Dun(BM bm) {
this.bm = bm;
}
@Override
public void run() {
while(true) {
synchronized (bm) {
num++;
if(num > 10) {
break;
}
if(bm.flag == true) {
try {
bm.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("蹲......");
bm.flag = true;
bm.notify();
}
}
}
}
class Qi implements Runnable{
private int num = 0;
private BM bm;
public Qi() {
}
public Qi(BM bm) {
this.bm = bm;
}
@Override
public void run() {
while(true) {
synchronized (bm) {
num++;
if(num > 10) {
break;
}
if(bm.flag == false) {
try {
bm.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("起......");
bm.flag =false;
bm.notify();
}
}
}
}
测试类
public class Test {
public static void main(String[] args) {
BM bm = new BM();
Thread t1 = new Thread(bm);
t1.start();
}
}
代码示例
/*
* 键盘输入
* 1.红色打印
* 2.黑色打印
* 根据输入数字的不同进行打印(打印"接口回调"即可)
*
* 定义一个接口
* 接口方法: 要求可以接收一个字符串做参数
*
* 定义一个功能类
* 要求: 接收一个接口对象作为参数 利用接口对象调用接口方法
*
* 定义两个类 实现接口
* 第1个类 普通打印
* 第2个类 错误(err)打印
*/
public class Demo01 {
public static void main(String[] args) {
System.out.println("请输入 1.红色 2.黑色");
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
Inter inter = null;
if(num == 1) {
inter = new RedPrint();
}else {
inter = new BlackPrint();
}
PrintClass.print(inter);
}
}
interface Inter{
public abstract void printS(String string);
}
class PrintClass{
public static void print(Inter inter) {
inter.printS("接口回调");
}
}
class RedPrint implements Inter{
@Override
public void printS(String string) {
System.err.println(string);
}
}
class BlackPrint implements Inter{
@Override
public void printS(String string) {
System.out.println(string);
}
}
回调代码示例
接口类
package com.lanou3g.hd;
public interface ReadFileInter {
public abstract void readFile(String string);
}
Read类
package com.lanou3g.hd;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Read {
public static void printFile(ReadFileInter inter) {
new Thread(new Runnable() {
@Override
public void run() {
FileInputStream fis = null;
BufferedInputStream bos = null;
try {
fis = new FileInputStream("/Users/lanou/Desktop/test3/kkk.txt");
bos = new BufferedInputStream(fis);
int len = 0;
byte[] b = new byte[1024];
while((len = bos.read(b)) != -1) {
inter.readFile(new String(b, 0, len));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
测试类
package com.lanou3g.hd;
public class Demo02 {
public static void main(String[] args) {
System.out.println("主线程实现逻辑一......");
Read.printFile(new ReadFileInter() {
@Override
public void readFile(String string) {
System.out.println(string);
}
});
System.out.println("主线程实现逻辑一......");
}
}
join方法
谁调用jion方法 谁就先执行完毕
public class p03 {
public static void main(String[] args) throws InterruptedException {
ImplRunnable implRunnable = new ImplRunnable();
Thread thread = new Thread(implRunnable);
thread.start();
thread.join();
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
System.out.println("我是主线程 线程");
}
}
}
class ImplRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我是子线程" + " " + i);
}
}
}
volatile
当不同线程中用到同一变量时,如
果某一线程中,变量的值发生变化,使用此关键字可以同步不同线程内此变量的值.
package com.lanou3g;
public class Demo04 {
public static void main(String[] args) {
VolRunnable runnable = new VolRunnable();
Thread t1 = new Thread(runnable);
t1.start();
while(!runnable.isOver) {
}
System.out.println("主线程结束了");
}
}
class VolRunnable implements Runnable{
public volatile boolean isOver = false;
int num = 0;
@Override
public void run() {
while(!isOver) {
num++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + num);
if(num > 5) {
isOver = true;
}
}
}
}
理解
当子线程中没有加sleep方法 和 volatile关键字时,子线程执行过快,在主线程还没有执行到while语句时,isOver的值已经更改
变成了true,这时主线程中的while语句中的条件为false,不会进去循环,因此没有卡主线程
执行结果:Thread-0 1
Thread-0 2
Thread-0 3
Thread-0 4
Thread-0 5
Thread-0 6
主线程结束了
会直接结束
当子线程中加入sleep方法,没有加volatile关键字时,大大的拖延了子线程的执行时间,使主线程执行到while语句时,
子线程中的isOver的值没有来得及更改,还是false,这时主线程中while中的条件便是true,进入循环,卡主了线程,一直在while循环中
当加入volatile修饰时,不管有没有sleep方法,isOver的值会立刻被刷新出去,while每次循环都会判断循环条件,因此主线程会顺利借宿,不会卡主
package com.lanou3g;
public class Demo06 {
public static void main(String[] args) {
ABRunnable volRun = new ABRunnable();
Thread tA = new Thread(volRun, "线程A");
Thread tB = new Thread(volRun, "线程B");
tA.start();
tB.start();
}
}
class ABRunnable implements Runnable{
private boolean flag = false;
@Override
public void run() {
String name = Thread.currentThread().getName();
synchronized (this) {
if(name.equals("线程B") && flag == false) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < 5; i++) {
System.out.println("我是 " + name);
}
if(name.equals("线程A")) {
flag = true;
}
this.notify();
}
}
}