Java笔记杨枝12.3

Java等待唤醒机制

package prc02;

public class StudentDemo {
    public static void main(String[] args) {
        Student s = new Student();

        SetThread st = new SetThread(s);
        GetThread gt = new GetThread(s);

        Thread t1 = new Thread(st, "a");
        Thread t2 = new Thread(gt, "b");

        t1.start();
        t2.start();
    }
}
//学生类
public class Student {

    String name;
    int age ;
    //声明一个变量
    boolean flag ; //默认没有数据,如果true,则说明有数据


}
//消费者
public class GetThread implements Runnable {
    private Student s;

    public GetThread(Student s) {
        this.s = s;
    }

    public void run() {
        while (true) {
            synchronized (s) {
                if (!s.flag) {
                    try {
                        s.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(s.name + "---" + s.age);
                // 修改标记
                s.flag = false;// 消费者线程
                // 通知对方(t1线程),消费者线程没有数据类,赶紧来消费
                s.notify();// 唤醒t1线程....
            }

        }
    }
}
//生产者
package prc02;

public class SetThread implements Runnable {
    private Student s;

    // 用构造函数使得他们用的都是同一个对象资源
    public SetThread(Student s) {
        this.s = s;
    }

    private int x = 0;

    public void run() {
        while (true) {
            synchronized (s) {
                if (s.flag) {
                    try {
                        s.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (x % 2 == 0) {
                    // 设置学生数据
                    s.name = "杨枝";
                    s.age = 24;
                } else {
                    s.name = "小明";
                    s.age = 12;
                }
                x++;
                // 修改标记
                s.flag = true;// 有数据了
                // 通知t2:消费者线程来消费数据
                s.notify();// 唤醒等待这种状态...
            }
        }
    }
}

线程组
public ThreadGroup(String name)构造一个新线程组
public Thread(ThreadGroup group,Runnable target ,String name)

package prac03;

public class Prac03 {
public static void main(String[] args) {
    //method1();
    method2();
}

private static void method2() {
    ThreadGroup tg = new ThreadGroup("这是一个新的线程组") ;

    //public Thread(ThreadGroup group,Runnable target ,String name){}
    MyRunnable my = new MyRunnable() ;
    Thread t1 = new Thread(tg, my, "线程1") ;
    Thread t2 = new Thread(tg, my, "线程2") ;

    ThreadGroup tg1 = t1.getThreadGroup() ;
    ThreadGroup tg2 = t2.getThreadGroup() ;

    System.out.println(tg1.getName());
    System.out.println(tg2.getName());
    System.out.println(Thread.currentThread().getThreadGroup().getName());

    tg.setDaemon(true) ;

}

private static void method1() {
    MyRunnable my = new MyRunnable() ;

    Thread t1 = new Thread(my) ;
    Thread t2 = new Thread(my) ;
    //public final ThreadGroup getThreadGroup()返回该线程所属的线程组
    ThreadGroup tg1 = t1.getThreadGroup() ;
    ThreadGroup tg2 = t2.getThreadGroup() ;

    String name1 = tg1.getName() ;
    String name2 = tg2.getName() ;

    子线程默认的线程组名称:main线程
    System.out.println(name1);
    System.out.println(name2);

    System.out.println(Thread.currentThread().getThreadGroup().getName());
    t1.start() ;
    t2.start() ;
}
}
public class MyRunnable implements Runnable {

    @Override
    public void run() {
        for(int x = 0 ; x <100 ; x ++){
            System.out.println(Thread.currentThread().getName()+":"+x);
        }

    }

}

最终版生产者-消费者模式
将学生类成员变量私有化
提供两个同步方法
两个线程可以直接调用

public class StudentDemo {
    public static void main(String[] args) {
        Student s = new Student();

        SetThread st = new SetThread(s);
        GetThread gt = new GetThread(s);

        Thread t1 = new Thread(st, "a");
        Thread t2 = new Thread(gt, "b");

        t1.start();
        t2.start();
    }
}
//学生类
public class Student {
    private String name;
    private int age;
    private boolean flag; // 默认没有数据,如果true,则说明有数据

    public synchronized void set(String name, int age) {
        if (this.flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.name = name;
        this.age = age;

        // 修改标记
        this.flag = true;// 有数据了
        // 通知t2:消费者线程来消费数据
        this.notify();// 唤醒等待这种状态...
    }

    public synchronized void get() {
        if (!this.flag) {
            try {
                this.wait();// 调用的时候,会立即释放锁
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(this.name + "---" + this.age);
        // 修改标记
        this.flag = false;
        this.notify();// 唤醒t1线程....
    }

}
//消费者
public class GetThread implements Runnable {
    private Student s;

    public GetThread(Student s) {
        this.s = s;
    }

    public void run() {
        while (true) {

            s.get();

        }
    }
}
//生产者
public class SetThread implements Runnable {
    private Student s;

    // 用构造函数使得他们用的都是同一个对象资源
    public SetThread(Student s) {
        this.s = s;
    }

    private int x = 0;

    public void run() {
        while (true) {
            if (x % 2 == 0) {
                s.set("小王", 32);
            } else {
                s.set("小明", 22);
            }
            x++;
        }
    }
}

线程池
很多子线程调用完毕不会立即被回收掉,而是会回到线程池中被多次利用(节约成本)

public class MyRunnable implements Runnable {

    @Override
    public void run() {
        //for循环
        for(int x = 0 ; x < 100 ; x ++){
            System.out.println(Thread.currentThread().getName()+":"+x);
        }
    }

}
//测试类
public class ExecutorsDemo {

    public static void main(String[] args) {

        //创建线程池对象,使用Executors工厂类
//public static ExecutorService newFixedThreadPool(int nThreads)
ExecutorService pool = Executors.newFixedThreadPool(2) ;

        //下来使用ExecutorService(跟踪多个异步任务)一些方法

        //使用submit(Runnable target):提交多个任务
        pool.submit(new MyRunnable()) ;
        pool.submit(new MyRunnable()) ;

        //结束线程池
        pool.shutdown() ;

    }
}

多线程的第三种实现方式
实现Callable接口

package prac04;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Prac04 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
    ExecutorService pool = Executors.newFixedThreadPool(2) ;
   //相当于start()
Future<Integer>f1=pool.submit(new MyCallable(100));
Integer i1= f1.get();
Future<Integer>f2=pool.submit(new MyCallable(10));
Integer i2= f2.get();
    System.out.println(i1);
    System.out.println(i2);
   pool.shutdown();
}
}
package prac04;

import java.util.concurrent.Callable;

public class MyCallable implements Callable<Integer>{
    private int number ;
    public MyCallable(int number){
        this.number = number ;
    }
    @Override
    public Integer call() throws Exception {
        int sum=0;
        for(int x = 0 ; x < number ; x ++){
        sum+=x;
        }
        return sum;
    }

}

定时器 Timer:

public void schedule(TimerTask task,Date time)安排在指定的时间执行指定的任务
public void schedule(TimerTask task, long delay)在多少毫秒后执行指定任务
public void schedule(TimerTask task, long delay, long period)
在多少毫秒后,执行任务,并且每个多少毫秒重复执行
public void cancel()终止此计时器,丢弃所有当前已安排的任务

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值