相关方法介绍:
代码演示
生产资源类:
public class Increase extends Thread {
student student;
int i=0;
public Increase(student student ) {
this.student=student;
}
@Override
public void run() {
while(true){
synchronized (student){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(student.flag){ //当资源存在时,进入等待时间
try {
student.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
if(i%2==0){
student.name="张三";
student.age=18;
}else{
student.name="李四";
student.age=25;
}
i++;
student.flag=true;//更改标记状态
student.notify();//唤起线程
}
}
}
}
消费资源类
public class Decrease extends Thread {
student student;
public Decrease(student student) {
this.student = student;
}
@Override
public void run() {
while(true){
synchronized (student){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(!student.flag){
try {
student.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(student.name+"==="+student.age);
student.flag=false;
student.notify();
}
}
}
}
变量类
public class student {
public static String name;
public static int age;
public static boolean flag =false;//标记,用来表示资源是否存在,false无、true有
}
volatile 关键字:当多个线程进行操作共享数据时,可以保证内存中的数据可见。
解释: 当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值,避免了多线程因不能及时更新内存,导致数据错乱问题;
volatile 变量,用来确保将变量的更新操作通知到其他线程。
CAS算法:比较并交换
内存值与自己的预估值进行比较,若相等对内存值进行修改;不相等,就不进行任何操作(把普通变量换成原子变量AtomicInteger I = new AtomicInteger(1),调用getAndIncrement()方法进行自加)
CAS算法比Synchronized效率高
原有一次创建一个线程,当需要多个线程时,就会大大的不方便,而使用线程池可以很好的提高性能,线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。JDK5可以使用Executors工厂类来产生线程池;
方法介绍:
代码演示
public class test {
public static void main(String[] args) {
ExecutorService t = Executors.newCachedThreadPool();//更具任务个数
ExecutorService t1 = Executors.newFixedThreadPool(2);//固定2个xiancheng
ExecutorService t2 = Executors.newSingleThreadExecutor();//当个线程
t.submit(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"我好困呀!!");
}
});
t1.submit(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"眼睛花了!!");
}
});
t1.submit(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"汗水哗啦啦!!");
}
});
t2.submit(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"夏天的西安真热!!");
}
});
t.shutdown();
t1.shutdown();
t2.shutdown();
}
}
定时器概述:定时器是一个应用十分广泛的线程工具,可用于调度多个定时任务以后台线程的方式执行。
可以通过Timer和TimerTask类来实现定义调度的功能。
Timer和TimerTask
Timer方法:
public Timer()
public void schedule(TimerTask task, long delay);
public void schedule(TimerTask task,long delay,long period);
public void schedule(TimerTask task, Date time):
public void schedule(TimerTask task, Date firstTime, long period):
TimerTask方法:定时任务
public abstract void run()
public boolean cancel() //关闭定时器
代码演示:
public class test {
public static void main(String[] args) throws ParseException {
Timer timer = new Timer();
timer.schedule(new TimerTask() {//在2019-7-31 21:24:00时,执行任务
@Override
public void run() {
System.out.println("我再练习啦啦。");
}
},new SimpleDateFormat("yyyy-mm-dd hh:mm:ss").parse("2019-7-31 21:24:00"));
timer.schedule(new TimerTask() {//运行后一秒执行
@Override
public void run() {
System.out.println("我再练习哈哈。");
}
},1000);
timer.schedule(new TimerTask() {//运行后一秒执行,然后每隔一秒执行一次
@Override
public void run() {
System.out.println("我再练习哈哈。吼吼");
}
},1000,1000);
}
}
Sleep()与wait()方法的区别
共同点:使线程,处于阻塞状态
Sleep必须设置时间 wait()可以不设置时间
Sleep方法:线程阻塞后,不释放锁
Wait方法:线程阻塞后,释放锁
单例模式:一个类只能有一个对象;
懒汉式:
对象类实现
public class student {
private static student stu =null;
public static student getStu(){
if(stu==null){
stu= new student();
}
return stu;
}
}
测试类实现:
public class test {
public static void main(String[] args) {
student stu = student.getStu();
student stu1 = student.getStu();
System.out.println(stu==stu1);
}
}
饿汉式:
public class student1 {
private static student1 stu= new student1 ();
public static student1 getStu(){
return stu;
}
}
测试类实现:
public class test1 {
public static void main(String[] args) {
student1 stu = student1.getStu();
student1 stu1 = student1.getStu();
System.out.println(stu==stu1);
}
}
Runtime类:单例模式的应用
每个Java应用程序都有一个Runtime 类实例,使应用程序能够与其运行的环境相连接。可以通过 getRuntime 方法获取当前运行时。
特有方法:public Process exec(String command) //执行Dos 命令
代码实现:
public class test3 {
public static void main(String[] args) throws IOException {
Runtime runtime = Runtime.getRuntime();
runtime.exec("calc");//打开电脑计算器
}
}