超牛牪犇Java之wait方法notify方法join方法setDeamon方法&接口回调

一.wait和notify

wait是让线程进入等待状态

notify是随即唤醒一个等待中的线程并释放锁(在执行完整个同步代码块后)

notifyAll是唤醒所有等待的线程

example:

开启两个线程A和B 先打印五遍线程B再打印五遍线程A

class ABRunnable implements Runnable {
	//声明一个标记来解决A先进来的问题
	private boolean flag = false;
	// 声明一把锁
	private Object object = new Object();
	@Override
	public void run() {
		// 循环打印AB 并打印线程名字
		String name = Thread.currentThread().getName();
		System.out.println(name + "进来了");
		//加同步锁
		//运行结果很随机 有时会卡住
		//A先进来会卡住 B先进来运行正确
		synchronized (object) {
			if (name.equals("线程B") && !flag) {
				//进入等待
				try {
					//如果B线程等待时 还拿着锁的话 会有什么现象
					//当线程进入等待的时候会释放锁
					//在哪个位置等待的 就从哪个位置被唤醒
					object.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				for (int i = 0; i < 5; i++) {
					System.out.println(name);
				}
			}
			for (int i = 0; i < 5; i++) {
				System.out.println(name);
			}
			//如果线程A打印完了 线程B就不需要再等待了 直接打印就行
			if (name.equals("线程A")) {
				flag = true;
			}
			object.notify();
		}
	}
}

创建线程并开启

public static void main(String[] args) {
		ABRunnable runnable = new ABRunnable();
		Thread t1 = new Thread(runnable, "线程A");
		Thread t2 = new Thread(runnable, "线程B");
		t1.start();
		t2.start();
}

单例饿汉式:如何保证多个线程调用时的安全性以及如何提高效率

class HungryMan {
	// 延迟加载(等调用方法的时候在创建对象)
	private static HungryMan hungryMan = null;

	// 私有化构造方法(不让外界创建对象 对象由自己创建)
	private HungryMan() {
		// TODO Auto-generated constructor stub
	}

	public static HungryMan getInstance() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 在多线程程序中 这个单例安全吗 为什么
		// 例如多个线程 调用该方法
		// 加锁来保证同一时间只有一个线程来创建对象
		//提高效率
		if (hungryMan == null) {
			synchronized (HungryMan.class) {
					hungryMan = new HungryMan();
			}
		}
		return hungryMan;
	}
}
class HungryRunnable implements Runnable{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			HungryMan hungryMan = HungryMan.getInstance();
			System.out.println(hungryMan);
		}
	}
	
}

join方法:  哪个线程调用了这个方法 就会拿到CPU的执行权 先完成执行

setDeamon: (守护线程)该方法必须在线程启动前调用 在主线程结束时结束

(并不是立即结束 需要一个缓冲时间)

example:

开启子线程循环打印十次 主线程循环打印十次 先打印子线程再打印主线程

class SonRunnable implements Runnable{

	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println(Thread.currentThread().getName());
		}	
	}
}class TestRunnable implements Runnable{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			
			System.out.println("测试");
		}
	

主线程:

public static void main(String[] args) {
		TestRunnable testRunnable = new TestRunnable();
		Thread t2 = new Thread(testRunnable);
		//该方法必须在线程启动前调用
		t2.setDaemon(true);
		t2.start();
		SonRunnable sr = new SonRunnable();
		Thread t1 = new Thread(sr);	
		t1.start();
		//哪个线程调用了这个方法 就会拿到CPU的执行权
		//先完成执行 
		try {
			t1.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		for (int i = 0; i < 10; i++) {
			System.out.println(Thread.currentThread().getName());
		}
		
		System.out.println("主线程结束了");
}

二.接口回调

写法:

1.创建一个接口

2.写一个功能类(打印字符串的方法的参数 可以使用借口来接收 达到调用接口中方法的目的)

3.写实现类

example:

键盘输入1或2 输入1的时候打印红色的字 输入2的时候打印黑色的字

System.err.println("哈哈"); 打印的是红色的

System.out.println("呵呵"); 打印的是黑色的


创建接口:
//接口
interface PrintInter{
	//打印方法
	public abstract void print(String string);
}
class PrintClass{
	//打印方法(接收接口的参数)
	public static void printString(PrintInter inter) {
		//调用接口中的方法
		inter.print("接口回调");
	}
}

写实现类:

class PrintRed implements PrintInter{

	@Override
	public void print(String string) {
		System.err.println(string);
	}
	
}
class PrintBlack implements PrintInter{

	@Override
	public void print(String string) {
		System.out.println(string);
	}
	
}

或者直接在main函数中写匿名内部类:

public static void main(String[] args) {
		System.out.println("请输入 1 或 2 ");
		Scanner scanner = new Scanner(System.in);
		String string = scanner.nextLine();
		PrintInter inter = null;
		if (string.equals("1")) {
			PrintClass.printString(new PrintInter() {
				@Override
				public void print(String string) {
					System.err.println(string);
				}
			});
		}else {
			PrintClass.printString(new PrintInter() {
				@Override
				public void print(String string) {
					System.out.println(string);
				}
			});
		}
		//调用功能类方法
		PrintClass.printString(inter);
	}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值