Java之多线程加强(多线程调度与控制)
来源:互联网 发布:卡通农场数据恢复 编辑:程序博客网 时间:2024/04/30 00:48
Java基础知识学了好久了,今天再拿来复习一下。
helloworld
先来一个helloworld热热身
Test.java
package cn.hncu.thread.hello;public class Test {public static void main(String[] args) {MyThread mt1=new MyThread(0);//偶数MyThread mt2=new MyThread(1); //奇数mt1.start();mt2.start();MyRun mr1=new MyRun(50);Thread t3=new Thread(mr1);MyRun mr2=new MyRun(51);Thread t4=new Thread(mr2);t3.start();t4.start();}}
MyThread.java
package cn.hncu.thread.hello;public class MyThread extends Thread{Integer first; public MyThread(Integer first) {this.first=first;}@Overridepublic void run() {for(int i=first;i<50;i+=2){System.out.print(i+" ");}System.out.println();}}
MyRun.java
package cn.hncu.thread.hello;public class MyRun implements Runnable{Integer first;public MyRun(Integer first) {this.first=first;}@Overridepublic void run() {for(int i=first;i<100;i+=2){System.out.print(i+" ");}System.out.println();}}
new出来了四个线程跑跑
多线程调度与控制
这里将通过四个版本代码来演示多线程调度与控制
v1版本
★ Java的多线程是抢占式的运行方式。 ★ setPriority()
★ sleep()方法
Thread类的sleep()方法对当前线程操作,是静态方法。sleep()的参数指定以毫秒为单位的线程休眠时间。除非因为中断而提早恢复执行,否则线程不会在这段时间之前恢复执行。
★ interrupt()方法
一个线程可以调用另外一个线程的interrupt()方法,这将向暂停的线程发出一个InterruptedException。变相起到唤醒暂停线程的功能。Thread类的方法interrupt(),是一种强制唤醒的技术。
Schedule.javapackage cn.hncu.thread.schedule.v1;public class Schedule {public static void main(String[] args) {MyThread t1=new MyThread(0);MyThread t2=new MyThread(1);//setPriority() 相对调度//t1.setPriority(5);//t2.setPriority(6);t1.start();//t1.start(); //如果一个线程已经启动,再次启动会出异常java.lang.IllegalThreadStateExceptiont2.start();//唤醒别人t1.interrupt(); //mian 线程强制唤醒t1,如果t1正在sleep,那么就停止sleep,往后继续执行代码}}
MyThread.java
package cn.hncu.thread.schedule.v1;public class MyThread extends Thread{private Integer first;public MyThread(Integer first) {this.first=first;}@Overridepublic void run() {if(first==0){try {Thread.sleep(1000); //主动睡1000毫秒=1s} catch (InterruptedException e) {System.out.println("我被强制唤醒了.......要继续干活了");}}for(int i=first;i<50;i+=2){System.out.print(i+" ");}System.out.println();}}
v2版本
★ yield()方法
用来使具有相同优先级的线程获得执行的机会。如果具有相同优先级的其它线程是可运行的,yield()将把线程放到可运行池中并使另一个线程运行。如果没有相同优先级的可运行线程,则什么都不做。
注意,执行一次yield()方法,该线程只是放弃当前这一次机会,然后又会重新和其它线程一起抢占CPU,很可能又比其它线程先抢到。
★ join()方法
调用某线程的该方法,将当前线程与该线程“合并”,即等待该线程结束,再恢复当前线程的运行。它可以实现线程合并的功能,经常用于线程的绝对调度。
Schedule.javapackage cn.hncu.thread.schedule.v2;public class Schedule {public static void main(String[] args) {MyThread t1=new MyThread(0);MyThread t2=new MyThread(1);//setPriority() 相对调度t1.setPriority(6);t2.setPriority(6);t1.start();try {t1.join(); //把t1线程剩下的代码合并到当前线程来执行。即:把t1线程中剩下的代码在此处先执行完,再执行后面的代码} catch (InterruptedException e) {System.out.println("线程合并异常.....");}t2.start();}}
MyThread.java
package cn.hncu.thread.schedule.v2;public class MyThread extends Thread{private Integer first;public MyThread(Integer first) {this.first=first;}@Overridepublic void run() {//if(first==0)//yield(); //主动让一次,且把机会让给其他同优先级的线程,否则什么也不做for(int i=first;i<50;i+=2){System.out.print(i+" ");}System.out.println();}}
v3版本
★ wait()方法
当前线程进入对象的waitpool。
★notify()/notifyAll()方法
唤醒对象的waitpool中的一个/所有等待线程。
★suspend()、resume()和stop()这几个方法现在已经不提倡使用。
Schedule.javapackage cn.hncu.thread.schedule.v3;public class Schedule {public static void main(String[] args) {Object obj=new Object();MyThread t1=new MyThread(0,obj);MyThread t2=new MyThread(1,obj);t1.start();t2.start();}}
MyThread.java
package cn.hncu.thread.schedule.v3;public class MyThread extends Thread{private Integer first;private Object obj;private static boolean isWait=true;public MyThread(int first, Object obj) {this.first=first;this.obj=obj;}@Overridepublic void run() {synchronized(obj){for(int i=first;i<50;i+=2){if(first==1&&i>25&&isWait){isWait=false;try {obj.wait();} catch (InterruptedException e) {System.out.println("被唤醒了.......");}}System.out.print(i+" ");}System.out.println();if(first==0){isWait=false; //为防止0线程先行拿到锁执行完毕以后,1线程一直waitobj.notify(); //只通知那些和自己处于同一等待池中的线程(被同一对象锁困住),任选一个//obj.notifyAll();//唤醒池中所有等待的线程}} //还锁}}
v4版本
Schedule.java
package cn.hncu.thread.schedule.v4;public class Schedule {public static void main(String[] args) {MyRun r=new MyRun();Thread t1=new Thread(r);Thread t2=new Thread(r);t1.start();t2.start();}}
MyRun.java
package cn.hncu.thread.schedule.v4;public class MyRun implements Runnable{private boolean isWait=true;@Overridepublic void run() {synchronized(this){for(int i=0;i<100;i+=2){if(i>50&&isWait){isWait=false;try {wait(); //会释放锁} catch (InterruptedException e) {System.out.println("被唤醒了....");}}System.out.print(i+" ");}System.out.println();notify();} //还锁}}
一个线程跑到50就等待,另外一个线程开始跑
线程互斥加强(互斥锁)
★带互斥的共享栈
多线程互斥共享“栈”资源
Client.javapackage cn.hncu.thread.shareStack;public class Client {public static void main(String[] args) {MyStack ms=new MyStack();PushThread push=new PushThread(ms);PopThread pop=new PopThread(ms);push.start();pop.start();}}
MyStack.java
package cn.hncu.thread.shareStack;public class MyStack {int idx=0;char data[]=new char[6];public void push(char ch){//同步块 对象直接指定synchronized(this){ //用this当对象锁data[idx++]=ch;System.out.println("push :"+ch);this.notify();}}//同步方法: 对象锁是该方法的拥有者 ---静态方法是类,非静态方法是this对象public synchronized char pop(){ //this对象锁if(idx<1){try {wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("pop :"+data[--idx]);return data[idx];}}
PushThread.java
package cn.hncu.thread.shareStack;public class PushThread extends Thread{private MyStack stack;public PushThread(MyStack stack) {this.stack=stack;}@Overridepublic void run() {for(int i=65;i<70;i++){stack.push((char) i);}}}
PopThread.java
package cn.hncu.thread.shareStack;public class PopThread extends Thread{private MyStack stack;public PopThread(MyStack stack) {this.stack=stack;}@Overridepublic void run() {for(int i=65;i<70;i++){stack.pop();}}}
★多窗口卖票
多线程互斥共享“基本数据类型数据”资源
版本一TicketSale.java
package cn.hncu.thread.ticket.v1;public class TicketSale {public static void main(String[] args) {//开四个窗口 让它们都开始卖票(启动线程)TicketWindow tw=new TicketWindow("窗口 ");Thread t1=new Thread(tw);Thread t2=new Thread(tw);Thread t3=new Thread(tw);Thread t4=new Thread(tw);t1.start();t2.start();t3.start();t4.start();}}
TicketWindow.java
package cn.hncu.thread.ticket.v1;public class TicketWindow implements Runnable {private Integer num = 200; // 共享变量(基本数据类型的数据) 不能当对象锁---因为他不是对象private Object obj = new Object();// 可以新建一个与基本数据类型共享变量平行的对象,来替代它当锁private String name;public TicketWindow(String name) {this.name = name;}@Overridepublic void run() {synchronized (obj) { // 拿锁--对象锁// synchronized(this){ //直接用this作对象锁也是可以的----非静态变量的对象锁是可以用this替代while (true) {if (num> 0) {System.out.println(name +": " + num);num--;}else{break;}}}//解锁---还锁}}//非静态变量要当对象锁时,直接用this代替(不需要再另外造对象),无论该变量是否为对象
版本二
TicketSale.java
package cn.hncu.thread.ticket.v2;public class TicketSale {public static void main(String[] args) {//开四个窗口 让它们都开始卖票(启动线程)Thread t1=new Thread(new TicketWindow("窗口1 "));Thread t2=new Thread(new TicketWindow("窗口2 "));Thread t3=new Thread(new TicketWindow("窗口3 "));Thread t4=new Thread(new TicketWindow("窗口4 "));t2.start();t1.start();t4.start();t3.start();}}
TicketWindow.java
package cn.hncu.thread.ticket.v2;public class TicketWindow implements Runnable {private static Integer num = 200; // 共享变量(基本数据类型的数据) 不能当对象锁---因为他不是对象private static Object obj = new Object();// 可以新建一个与基本数据类型共享变量平行的对象,来替代它当锁private String name;public TicketWindow(String name) {this.name = name;}@Overridepublic void run() {while(true){synchronized (obj) {//※静态变量的对象锁是不能用this来代替的if (num > 0) {System.out.println(name + ":" + num);num--;} else {break;}}}}}
两个版本一个用了非静态变量作锁,一个用了静态变量作锁,两者还是有差别的。
- Java之多线程加强(多线程调度与控制)
- java--多线程调度与控制1
- java--多线程调度与控制2
- Java多线程的调度与控制
- C#多线程控制进度条之多线程安全
- 多线程学习之多线程的控制
- java多线程之多线程的线程安全问题
- (45)Java学习笔记——多线程 / 设置线程 / 线程调度 /线程控制
- 线程的调度与控制
- java---多线程调度与控制常见方法一览
- Java多线程:线程调度Join
- Java多线程-线程的调度
- 基础加强6之多线程
- Java中的多线程(一)之多线程创建
- Java中的多线程(二)之多线程同步
- JAVA多线程之多线程的实现
- 【java基础之多线程】多线程的创建
- 【java基础之多线程】多线程的生命周期
- Leetcode——32. Longest Valid Parentheses
- weka之ID3
- VIM编辑技巧之把单词大小写转换
- 读书笔记《Effective C++》条款31:将文件间的编译依存关系降至最低
- 热键与快捷键的区别
- Java之多线程加强(多线程调度与控制)
- 初识.net界面程序(11)--实现界面登陆
- linux配置java环境变量(详细)
- Html-Css基础知识
- python中的装饰器
- asks to run as user -2 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_
- Ajax学习(三):XML及Json与Ajax配合使用
- Android毕业设计及论文答辩经验分享
- 图像