滨州网站定制,百度seo免费推广教程,挖矿网站怎么免费建设,线上注册公司流程和费用一、 多线程概念和作用 线程指进程中的一个执行场景#xff0c;也就是执行流程#xff0c;那么进程和线程的区别是什么 1.每个进程是一个应用程序#xff0c;都有独立的内存空间 2.同一个进程中的线程共享其进程中的内存和资源 (共享的内存是堆内存和方法内存#xff0c;栈… 一、 多线程概念和作用 线程指进程中的一个执行场景也就是执行流程那么进程和线程的区别是什么 1.每个进程是一个应用程序都有独立的内存空间 2.同一个进程中的线程共享其进程中的内存和资源 (共享的内存是堆内存和方法内存栈内存不共享每个线程有自己的堆内存) 进程进程对应一个应用程序 现在的计算机都是支持多进程的在同一个操作系统中可以同时启动多个进程 多进程的作用 * 单进程只能做一件事 : 一边玩游戏一边听音乐不是同时运行而是进程之间的频繁调度切换速度极高感觉是同时进行。 * 多线程的作用不是提高执行速度而是提高CPU的使用率。进程和进程之间的内存是独立的、 * 线程是进程中的执行场景。一个进程可以启动多个线程。 * 多线程的作用不是为了提高执行速度而是为了提高应用程序的使用率 * java程序的运行原理 * java命令启动java虚拟机启动JVM等于启动一个应用程序表明启动一个进程。该进程会自动启动一个“主线程”然后主线程去调用某各类的main方法。 * 所以main方法运行在主线程中。在此之前的所有程序都是单线程的。 二、线程的创建和启动 *Java虚拟机的主线程入口是main方法用户可以自己创建线程创建方式有两种 *1.继承Thread类 *2.实现Runnable接口(推荐使用Runnable) *继承Thread类 *采用 Thread类创建线程,用户只需要继承 Thread,覆盖 Thread中的run方法,父类 Thread中的run方法没有抛出异常,那么子类也不角能抛出异常,最后采用start启动线程即可 实现Runnable接口 Thread对象本身就实现了 Runnable接口,但一般建议直接使用 Runnable接口来写多线程程序,因为接口会比类带来更多的好处 三、java语言中实现多线程第一种方式 1.继承java.lang.Thread 2.重写run方法 三个知识点 定义线程 、创建线程、 启动线程 package com.steven.demo;import java.lang.Thread;
public class ThreadTest {public static void main(String[] args) {Thread thread new Student();//启动线程thread.start();//打印Run:0~9//start方法执行完瞬间结束告诉JVM再分配一个新的线程 给t线程//是随机分配的没有规律//run不需要手动调用系统程序启动之后会自动调用方法//thread.run();//这是普通方法的调用这样做程序只有一个线程run方法结束之后下边的程序才会执行for (int i 0; i 5; i) {System.out.println(maini);}//有了多线程之后main方法结束只是主线程中没有方法栈帧了 但是其他线程或者其他栈中还有栈帧 main方法结束程序可能还在运行}
}class Student extends Thread {//重写Run方法public void run() {for (int i 0; i 10; i) {System.out.println(Run:i);}}
} 四、java语言中实现多线程第二种方式 1.写一个类实现 2.重写run方法 package com.steven.demo;import java.lang.Runnable;
import java.lang.Thread;
public class ThreadTest02 {public static void main(String[] args) {//创建线程:Thread thread new Thread(new Teacher());//启动线程thread.start();}
}
class Teacher implements Runnable {//重写Run方法public void run() {for (int i 0; i 10; i) {System.out.println(Run:i);}}
} 五、掌握线程方法 1.获取当前线程的对象 Thread.currentThread() 2.给线程起名t.setName() 3.获取线程的名字:t.getName() package com.steven.demo;
public class ThreadTest03 {public static void main(String[] args) {//获取当前线程的对象 main主线程Thread thread Thread.currentThread();//获取当前线程的名字System.out.println(当前名称的名称thread.getName());//当前名称的名称mainThread t1 new Thread(new ArrayTest());//给线程起名t1.setName(Steven);t1.start();//线程的名称StevenThread thread2 new Thread(new ArrayTest());//给线程重命名thread2.setName(珂珂);thread2.start();//线程的名称珂珂}
}
class ArrayTest implements Runnable {public void run() {Thread thread Thread.currentThread();//获取当前线程的对象System.out.println(线程的名称thread.getName());}
} 六、线程的优先级 优先级高的获取CPU时间片相对多一些 最高10 最小1 默认5 优先级1-10 优先级高的线程会得到CPU的时间多一些优先执行完成 public class ThreadTest04 {public static void main(String[] args) {System.out.println(最高Thread.MAX_PRIORITY);System.out.println(最小Thread.MIN_PRIORITY);System.out.println(默认Thread.NORM_PRIORITY);Thread t1 new Thread(new KeKe());t1.setName(t1);Thread t2 new Thread(new KeKe());t2.setName(t2);//获取线程的优先级System.out.println(t1优先级t1.getPriority());System.out.println(t2优先级t2.getPriority());//设置优先级t1.setPriority(5);t2.setPriority(6);//启动t1.start();t2.start();//线程虽然有优先级但是随机分配的打印结果不一致}
}
class KeKe extends Thread {public void run() {for (int i 0; i 10; i) {System.out.println(Thread.currentThread().getName()----------------i);}}
} 七、线程休眠 ①Thread.sleep()使当前正在执行的线程执行休眠操作(暂停执行) 单位毫秒 sleep 静态方法 作用: 阻塞当前线程腾出CPU让给其他线程 public class ThreadTest05 {public static void main(String[] args) {Thread thread new Array1();thread.setName(thread1);thread.start();//获取当前线程的对象 main主线程Thread t Thread.currentThread();//获取当前线程的名字System.out.println(当前名称的名称t.getName());//当前名称的名称main //阻塞主线程for (int i 0; i 10; i) {System.out.println(Thread.currentThread().getName() -------------------: i);try {Thread.sleep(2000);//程序休眠2秒钟} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
}
class Array1 extends Thread {public void run() {System.out.println(线程正在启动-);for (int i 0 ; i 5 ; i ) {System.out.println(Thread.currentThread().getName() -------------------: i);try {Thread.sleep(2000);//程序休眠2秒钟} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
} ②Thread.yield()暂停当前正在执行的线程对象并执行其他线程。 1.静态方法 2.作用给同一个优先级的线程让位但是让位时间不固定 3.和sleep方法相同就是yield的时间不固定 他与sleep类似只是不能由用户执行暂停时间并且yield()只能让同优先级的线程有执行的机会 package com.steven.demo;
public class ThreadTest07 {public static void main(String[] args) {//1.创建线程Thread thread new HThread();thread.setName(线程07);//2.启动线程thread.start();//3.主线程for (int i 0; i 10; i) {System.out.println(Thread.currentThread().getName() ---------:i);}System.out.println(Steven);}
}
class HThread extends Thread {public void run() {for (int i 0; i 10; i) {System.out.println(Thread.currentThread().getName() ---------:i);if (i % 2 0) {//暂定当前线程执行其他线程Thread.yield();}}}
} ③线程的基本操作 /*线程的基本操作创建启动休眠异常处理*/
public class ThreadTest06 {public static void main(String[] args) {try {//1.创建线程Thread thread new MyThread();thread.setName(线程);//2.启动线程thread.start();//3.休眠Thread.sleep(2000);System.out.println(Steven);}catch (InterruptedException e) {e.printStackTrace();} }
}class MyThread extends Thread {public void run() {for (int i 0; i 10; i) {try {Thread.sleep(3000);} catch (Exception e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() ---------:i);}}
} 八、线程的合并(join) public class ThreadTest08 {public static void main(String[] args) {try {//1.创建线程Thread thread new KThread();thread.setName(线程07);//2.启动线程thread.start();//3.合并线程 (线程07和main线程合并)thread.join();//输出只保证一个线程正在执行依次执行单线程的程序 (先执行线程07后执行main)//主线程for (int i 0; i 10; i) {System.out.println(Thread.currentThread().getName() ---------:i);} //当前线程可以调用第一个线程的join方法调用后当前线程会被阻塞不再执行直到被调用的线程执行完毕当前线程才会执行} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}
class KThread extends Thread {public void run() {for (int i 0; i 10; i) {try {Thread.sleep(2000);System.out.println(Thread.currentThread().getName() ---------:i);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();};}}
} 九、线程同步案例 1模拟取款不使用同步机制多线程同时对同一个账号进行取款操作 /*
模拟取款不使用同步机制多线程同时对同一个账号进行取款操作
thread 和 thread2
异步编程模型thread线程执行的是thread , thread2线程执行的是thread2 ,两个线程之间谁也不等于谁
同步编程模型thread线程和thread2线程执行当thread线程必须等thread2的线程的执行结果之后thread线程才能执行 这是同步编程什么时候需要引入同步
1.为了数据安全尽管程序的使用率低但是为了保证数据安全性必须得加入线程同步机制, 线程同步机制 使程序变成了单线程(一个线程)
2.在什么条件下需要使用线程同步
1必须是多线程环境
2多线程环境在共享同一个数据时
3共享的数据涉及到修改操作*/
package com.steven.demo;public class ThreadTest09 {public static void main(String[] args) {//创建一个公共的账户Account account new Account(steven_kou,10000.0);//创建线程对同一个账户进行取款Thread thread new Thread(new Money(account));thread.setName(steven);Thread thread2 new Thread(new Money(account));thread2.setName(kou);thread.start();thread2.start();}
}//取款线程
class Money implements Runnable {//账户Account account;Money (Account account){this.account account;}public void run() {account.withDraw(2000.0);System.out.println(取款2000.0$余额为account.getBalance());//取款2000.0$余额为8000.0 (输出两次)}}//银行账户
class Account {private String actno;private double balance;//账户余额public Account() {}public Account(String actno,double balance) {this.actno actno;//成员变量|局部变量this.balance balance;}public void setActno(String actno) {this.actno actno;}public String getActno() {return actno;}public void setBalance(double balance) {this.balance balance;}public double getBalance() {return balance;}//对外提供一个取款方法public void withDraw(double money) {//对账户进行取款操作double after balance - money;//延迟操作try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();//InterruptedException 线程中断下抛出的异常}this.setBalance(after);//更新账户余额重新赋值}
} 2模拟取款同步机制同步锁synchronized ①以下程序使用线程同步机制保证数据安全 package com.steven.demo;
public class ThreadTest09 {public static void main(String[] args) {//创建一个公共的账户Account account new Account(steven_kou,10000.0);//创建线程对同一个账户进行取款Thread thread new Thread(new Money(account));thread.setName(steven);Thread thread2 new Thread(new Money(account));thread2.setName(kou);thread.start();thread2.start();}
}//取款线程
class Money implements Runnable {//账户Account account;Money (Account account){this.account account;}public void run() {account.withDraw(2000.0);System.out.println(取款2000.0$余额为account.getBalance());//取款2000.0$余额为8000.0 (输出两次)}}//银行账户
class Account {private String actno;private double balance;//账户余额public Account() {}public Account(String actno,double balance) {this.actno actno;//成员变量|局部变量this.balance balance;}public void setActno(String actno) {this.actno actno;}public String getActno() {return actno;}public void setBalance(double balance) {this.balance balance;}public double getBalance() {return balance;}//对外提供一个取款方法//TODO 取款 同步public void withDraw(double money) {/*需要把同步的代码放到同步的语句块中thread线程执行到此处遇到了synchronized 关键字就会去找this的对象锁 如果找到了this的对象锁则进入同步语句块 执行程序当同步语句块代码执行结束的时候thread线程归还this的对象锁在thread线程执行同步语句块的过程中如果thread2线程也执行以下代码。遇到synchronized 关键字所以去找this对象锁但是该对象被thread线程持有, 只能等待thread线程使用完以后再解锁this对象锁*///同步锁synchronized (this) {//对账户进行取款操作double after balance - money;//延迟操作try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();//InterruptedException 线程中断下抛出的异常}//更新账户余额重新赋值this.setBalance(after);}}
} ②synchronized关键字 添加到成员方法上线程拿走的也是this对象锁 //对外提供一个取款方法//TODO 取款 同步//synchronized关键字 添加到成员方法上线程拿走的也是this对象锁public synchronized void withDraw(double money) {/*需要把同步的代码放到同步的语句块中thread线程执行到此处遇到了synchronized 关键字就会去找this的对象锁 如果找到了this的对象锁则进入同步语句块 执行程序当同步语句块代码执行结束的时候thread线程归还this的对象锁在thread线程执行同步语句块的过程中如果thread2线程也执行以下代码。遇到synchronized 关键字所以去找this对象锁但是该对象被thread线程持有, 只能等待thread线程使用完以后再解锁this对象锁*///同步锁
// synchronized (this) {//对账户进行取款操作double after balance - money;//延迟操作try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();//InterruptedException 线程中断下抛出的异常}//更新账户余额重新赋值this.setBalance(after);
// }} 三、守护线程 ①定义一个用户线程 package com.steven.demo;//定义一个用户线程
public class UserThread01 {public static void main(String[] args) {Runnable runnable new UserTest();Thread thread new Thread(runnable, UserThread);thread.start();for (int i 0; i 10; i) {System.out.println(Thread.currentThread().getName() i);}System.out.println(主线程结束---);}
}class UserTest implements Runnable {public void run() {for (int i 0; i 10; i) {System.out.println(Thread.currentThread().getName() i);}}
} ②改为守护线程 package com.steven.demo;
//守护线程
//其他所有的用户线程结束则守护线程退出
//守护线程一般都是无限执行的 守护线程最后结束(先执行用户线程)
//设置守护线程以后当前主线程结束后守护线程并没有把所有的数据输出就结束 也就是说 守护线程是为用户线程服务的当用户线程全部结束守护线程会自动化结束public class UserThread02 {public static void main(String[] args) {Thread thread new UserTest02();thread.setName(thread);//将thread这个用户线程 修改为守护线程thread.setDaemon(true);thread.start();//主线程 for (int i 0; i 10; i) {System.out.println(Thread.currentThread().getName() i);try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}System.out.println(主线程结束---);}
}
class UserTest02 extends Thread {public void run() {int i 0;while (true) {i ;System.out.println(Thread.currentThread().getName() :i);try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}}
} 四、定时器简单使用 package com.steven.demo;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;/*Timer 定时器*/
public class TimerTest01 {public static void main(String[] args) {System.out.println(来了); Timer timer new Timer();try {Date date new SimpleDateFormat(yyyy-MM-dd HH:mm:ss).parse(2018-10-07 19:26:02);//安排在指定的时间执行指定的任务timer.schedule(new MyTimer(), date,1000*60*60*24);//date执行后续任务的时间间隔 设置定时任务在2018-10-07 19:26:02执行此任务, 24小时执行一次//timer.schedule(new MyTimer(), date,1000*2);//如果设置每天执行一次Date date new SimpleDateFormat(HH:mm:ss).parse(19:26:02);}catch (ParseException e) {e.printStackTrace();} catch (NullPointerException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalStateException e) {e.printStackTrace();}}
}class MyTimer extends TimerTask {public void run() {System.out.println(new Date());//Sun Oct 07 19:26:02 CST 2018}} 转载于:https://www.cnblogs.com/StevenHuSir/p/Java_Thread.html