一.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 <www.leyouzaixian2.com 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 www.hjha178.com/ 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) www.chuangshi88.cn/{
- System.out.println("请输入 1 或 2 ");
- Scanner scanner = new Scanner(System.in);
- String string = scanner.nextLine();
- PrintInter inter = null;
- if (string.equals("www.douniu1956.com/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 www.yongshiyule178.com string) {
- System.out.println(string);
- }
- });
- }
- //调用功能类方法
- PrintClass.printString(inter);
- }