java多线程多态_Java学习之多线程

多线程:

(一)进程与线程

进程特点

f83928721de52a1532597639f856683c.png

并发与并行的区别:

7ea0d92ad3f51bfa73bae07512d425e7.png

多线程编程的好处:

7320fb21ce9e9396fb543c5ba76f963f.png

(二)多线程的建立

1,通过继承Thread类,代码如下:

class MyThread extendsThread {private static int K = 10;//类共享变量

private int M=10;//成员共享变量

MyThread(){super();

}

@Overridepublic voidrun() {

System.out.println("in MyThread run");for (int i = 0; i < 10; i++) {

System.out.println(Thread.currentThread().getName()+ "K:" + K--);

System.out.println(Thread.currentThread().getName()+ "M:" + M--);

}

}

}public classThreadDemo1 {public static voidmain(String[] args) {//多线程Thead方式1

MyThread thread2 = newMyThread();new Thread(thread2,"t2").start();//此时成员变量被共享,静态也被共享,k和M的结果为-9

new Thread(thread2,"t3").start();//多线程Thead方式1

MyThread thread3=new MyThread();//此时静态类变量被共享,k为-9,M为0.

thread2.start();

thread3.start();

}

}

2,通过实现Runnable接口(推荐),代码如下:

public classThreadDemo1 {public static voidmain(String[] args) {//RUNNABLE 方式2

MyRunnable myRunnable = newMyRunnable();new Thread(myRunnable,"t1").start();//此时成员变量被共享,静态也被共享,K和M为-9//RUNNABLE 方式2

new Thread(myRunnable,"t3").start();

MyRunnable myRunnable1= new MyRunnable();//此时成员变量不被共享,静态被共享,K为-9,M为0

new Thread(myRunnable,"t1").start();new Thread(myRunnable1,"t3").start();

}

}class MyRunnable implementsRunnable {private static int K = 10;private int M = 10;

@Overridepublic voidrun() {

System.out.println("in MyRunnable run");for (int i = 0; i < 10; i++) {

System.out.println(Thread.currentThread().getName()+ " K:" + (K--));

System.out.println(Thread.currentThread().getName()+ " M:" + (M--));

}

}

}

3,通过实现Callable接口和Future包装来建立:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

importjava.util.Random;importjava.util.concurrent.Callable;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.FutureTask;public classCallableThread {public static voidmain(String[] args) {

Callable callable = new Callable() {public Integer call() throwsException {return new Random().nextInt(100);

}

};

FutureTask future = new FutureTask(callable);newThread(future).start();try{

Thread.sleep(5000);//可能做一些事情

System.out.println(future.get());

}catch(InterruptedException e) {

e.printStackTrace();

}catch(ExecutionException e) {

e.printStackTrace();

}

}

}

View Code

三种建立多线程的优劣比较有:

9e8385e9176f429f2315fedafd7d57c5.png

(三)线程的生命周期

5224506f15d23aece54edce9cb0dd03a.png

Java线程具有五中基本状态

新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();

就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;

运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就     绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:

1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;

2.同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

3.其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

关键字:

yield:该线程让出CPU,进入就绪状态

join:该子线程优先执行,相当于方法调用,父线程进入IO阻塞状态

sleep:该线程让出CPU,进入IO阻塞状态,不释放对象锁

wait:同步锁下进行使用,该线程进入阻塞状态,释放对象锁

notify:唤醒wait下的线程,进入同步阻塞状态

synchronized:同步锁,未获得锁的线程进入同步阻塞状态

(五),多线程同步(Thread Synchronized)

线程同步即保证某个线程访问某个共享资源时,其他的线程需要wait,即有顺序性

(六),多线程案例

1,线程死锁案例:

/*死锁:

线程1:synchronized(o1) { Thread.sleep() synchronized(o2) }

线程2:synchronized(o2) { Thread.sleep() synchronized(o1) }

首先线程1执行,对o1加同步锁,其他线程无法访问,

然后线程1睡眠,让出cpu,线程2执行,锁住o2

线程1睡眠结束,继续执行,要对o2加同步锁,但被线程2占据,所以上不了锁,

处于等待获得o2同步锁的状态,且线程1不能结束,释放不了o1对象。

线程2睡眠结束,继续执行,要对o1加同步锁,但被线程1占据,所以上不了锁,

处于等待获得o1同步锁的状态,且线程2不能结束,故释放不了o2

故处于死锁状态。

死锁经典问题:哲学家问题

方法:加粗锁定对象*/

public class DeadThread implementsRunnable {private int flag=0;static Object object=new Object();//类变量,只有一份,每个实例共享

static Object object1=new Object();// public voidrun(){if (flag==0){synchronized (object) {//释放object同步锁,需要等object1锁释放,

System.out.println(flag);try{

Thread.sleep(40);

}catch(InterruptedException e) {

e.printStackTrace();

}synchronized(object1) {//System.out.println(flag);

}

}

}if (flag==1){synchronized (object1) {//释放object1同步锁,需要等object锁释放.两个线程互相等待中

System.out.println(flag);try{

Thread.sleep(400);

}catch(InterruptedException e) {

e.printStackTrace();

}synchronized(object) {//System.out.println(flag);

}

}

}

}public static voidmain(String[] args) {

DeadThread deadThread=newDeadThread();

DeadThread deadThread1=newDeadThread();

deadThread.flag=0;

deadThread.flag=1;

Thread thread=newThread(deadThread);

Thread thread1=newThread(deadThread1);

thread.start();

thread1.start();

}

}

2,多线程多态:

public classThreadTest {public static voidmain(String[] args) {for (int i = 0; i < 100; i++) {

System.out.println(Thread.currentThread().getName()+ " " +i);if (i == 30) {

Runnable myRunnable= newMyRunnable();

Thread thread= new MyThread(myRunnable);//输出的是MyThread中的Run方法,多态的体现

Thread thread1=new Thread(myRunnalbe);//输出myRunnable中run方法。

thread1.start();

thread.start();

}

}

}

}class MyRunnable implementsRunnable {private int i = 0;

@Overridepublic voidrun() {

System.out.println("in MyRunnable run");for (i = 0; i < 100; i++) {

System.out.println(Thread.currentThread().getName()+ " " +i);

}

}

}class MyThread extendsThread {private int i = 0;publicMyThread(Runnable runnable){super(runnable);

}

@Overridepublic voidrun() {

System.out.println("in MyThread run");for (i = 0; i < 100; i++) {

System.out.println(Thread.currentThread().getName()+ " " +i);

}

}

}

3,生产者消费者模型:

public classProducerConsumer {public static voidmain(String[] args) {

SycnStack ss=newSycnStack();

Runnable producer=newProducer(ss);

Runnable consumer=newConsumer(ss);new Thread(producer,"p1").start();/*new Thread(producer,"p2").start();

new Thread(producer,"p3").start();

new Thread(producer,"p4").start();

new Thread(producer,"p5").start();*/

new Thread(consumer,"c1").start();

}

}classWoTo{intid;

WoTo(intid){this.id=id;

}

@OverridepublicString toString() {return "WOTO"+":"+id;

}

}classSycnStack{

WoTo[] wotoArr=new WoTo[6];int index=0;public synchronized voidpush(WoTo woto){while (index==6){//wotoArr.length==6,当stack中满6个时,生产停止,需要消费者消费并notify生产者继续生产

try{

System.out.println("full");//发生wait后,如果没有notify唤醒写在wait的方法不执行。

this.wait();

}catch(InterruptedException e) {

e.printStackTrace();

}

}

wotoArr[index]=woto;

index+=1;this.notifyAll();//生产往后通知消费者,主要是唤醒消费者来消费,如果多线程也会唤醒生产者,但唤醒后任然可能会进入wait中

}public synchronizedWoTo pop(){while (index==0){try{

System.out.println("null");this.wait();

}catch(InterruptedException e) {

e.printStackTrace();

}

}

index-=1;this.notifyAll();//消费完后通知生产者,唤醒生产者来生产,注释掉会进入死锁状态即,消费者等生产者生产,而生产者在wait中。

returnwotoArr[index];

}

}class Producer implementsRunnable{

SycnStack ss=null;

Producer(SycnStack ss){this.ss=ss;

}

@Overridepublic voidrun() {for (int i=0;i<20;i+=1){//一个线程最多生产20个馒头

WoTo woto=newWoTo(i);

ss.push(woto);try{

Thread.sleep(200);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+":produce:"+woto);

}

}

}class Consumer implementsRunnable{

SycnStack ss=null;

Consumer(SycnStack ss){this.ss=ss;

}

@Overridepublic voidrun() {for(int i=0;i<20;i+=1){//一个消费者最多消费20个

WoTo woto=ss.pop();try{

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+":consuemer:"+woto);

}

}

}

4,笔试题1:

public class SyncThread1 implementsRunnable {int num=100;/*m1()和m2()都加了同步锁,执行流程显示调用run方法中的m1(),对num加同步锁,然后让出cpu,开始main线程

调用m2方法,不能访问不能修改num,结束然后,输出num,然后让出cpu,继续执行m1()方法。sleep并不代表结束就能马上运行,处于就绪状态

需抢占*/

synchronized voidm1(){

num=1000;try{

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println("num"+num);

}synchronized voidm2(){try{

Thread.sleep(500);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println(num);

num=2000;//System.out.println(num);

}public voidrun(){

m1();

}public static voidmain(String[] args) {

SyncThread1 syncThread1=newSyncThread1();

Thread thread=newThread(syncThread1);

thread.start();//新开的线程,不和main线程共线程

syncThread1.m2();//在main线程中,因为m2()加了同步锁,即对num加锁了,m2无法对num修改,即不执行,直接执行下面这个输出

System.out.println(syncThread1.num);//main线程要等syncThread1.m2()执行完才执行

}

}

5,哲学家问题:

/*问题描述:一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条。哲学家思考问题,

当饿了的时候拿起左右两只筷子吃饭,必须拿到两只筷子才能吃饭。上述问题会产生死锁的情况,

当5个哲学家都拿起自己右手边的筷子,准备拿左手边的筷子时产生死锁现象。

解决办法:

1、添加一个服务生,只有当经过服务生同意之后才能拿筷子,服务生负责避免死锁发生。

2、每个哲学家必须确定自己左右手的筷子都可用的时候,才能同时拿起两只筷子进餐,吃完之后同时放下两只筷子。

代码实现:实现第2种方案*/

public classPhilosopherDemo {public static voidmain(String[] args) {

Fork fork=newFork();//五个philosopher都指向同一个fork,所以此时相当于成员变量被多个线程共享了

Philosopher philosopher=new Philosopher(fork,0);

Philosopher philosopher1=new Philosopher(fork,1);

Philosopher philosopher2=new Philosopher(fork,2);

Philosopher philosopher3=new Philosopher(fork,3);

Philosopher philosopher4=new Philosopher(fork,4);newThread(philosopher).start();newThread(philosopher1).start();newThread(philosopher2).start();newThread(philosopher3).start();newThread(philosopher4).start();

}

}class Philosopher implementsRunnable{

Fork fork=null;intid;

Philosopher(Fork fork,intid){this.fork=fork;this.id=id;

}

@Overridepublic voidrun() {while(true){

think();

fork.getFork(this);

eat();

fork.offFork(this);

}

}public voidthink(){try{

System.out.println(id+"in thinking");

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}public voideat(){try{

System.out.println(id+"in eating");

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}classFork{boolean[] fork={false,false,false,false,false};//模拟五把叉

public synchronized voidgetFork(Philosopher p){while(fork[p.id]||fork[(p.id+1)%5]){

System.out.println("p:"+p.id+"waiting");try{

wait();

}catch(InterruptedException e) {

e.printStackTrace();

}

}

fork[p.id]=true;

fork[(p.id+1)%5]=true;

System.out.println("p:"+p.id+"getFork");

}public synchronized voidoffFork(Philosopher p){

fork[p.id]=false;

fork[(p.id+1)%5]=false;

System.out.println("p:"+p.id+"offFork");this.notifyAll();

}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/528234.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 执行存储过程报语法错误_为什么我在批处理从Java上执行PostgreSQL上的存储过程时收到错误通知“结果不合理”?...

我在数据库中有这个过程&#xff1a;CREATE OR REPLACE FUNCTION replacePageRelevance(id INT, value REAL) RETURNS VOID AS $$BEGININSERT INTO pageRelevance VALUES (id,value);EXCEPTION WHEN unique_violation THENUPDATE pageRelevance SET relevance value WHERE pag…

python staticmethod有什么意义_关于静态方法:python中的@staticmethod有什么意义?

为了更好地理解静态方法在Python中的工作方式&#xff0c;我开发了这个简短的测试/示例代码。class TestClass:def __init__(self, size):self.size sizedef instance(self):print("regular instance method - with self")staticmethoddef static():print("sta…

java fx border_JavaFx UI控件与代码间的绑定方法

JavaFx初探一&#xff0c;UI控件的使用&#xff0c;具体内容如下方式一&#xff1a;使用纯代码直接new view控件&#xff0c;这样就不涉及到与fxml文件之间的交互了方式二&#xff1a;使用fxml编写界面文件&#xff0c;用可视化工具scene builder 来构建交互界面。分两种方式绑…

java mysql ssl警告_连接到MySQL数据库时有关SSL连接的警告

用于初始化与MySQL服务器的连接的默认值在最近已更改&#xff0c;并且(通过快速查看堆栈溢出时最流行的问题和答案)新值引起了很多混乱。更糟糕的是&#xff0c;标准建议似乎是完全禁用SSL&#xff0c;这在制造过程中有点麻烦。现在&#xff0c;如果您的连接确实没有暴露给网络…

如何将php改成mp4,PHP 将视频转成 MP4 并获取视频预览图(用到ffmpeg)

搜索热词下面是编程之家 jb51.cc 通过网络收集整理的代码片段。编程之家小编现在分享给大家&#xff0c;也给大家做个参考。flv_convert_get_thumb(input.avi,output.jpg,output.ogm);// code provided and updated by steve of PHPsnaps ! thanks// accepts:// 1: the input v…

php无嵌套遍历多维数组,不递归怎么遍历多维数组(维数不定)

不递归如何遍历多维数组(维数不定)现有数组$tree array (array (ID > 1,PARENT > 0,NAME > 祖父,CHILD > array (array (ID > 3,PARENT > 1,NAME > 叔伯),array (ID > 4,PARENT > 1,NAME > 父亲,CHILD > array (array (ID > 5,PARENT >…

c 如何操作php,thinkphp的c方法使用示例

1.C方法的作用a. 加载设置用户的配置&#xff0c;保存在一个C函数内的静态变量$_config 中b. 读取用户的配置 (从$_congig 中读取)2. 需求分析:1.设置变量1.二维数组C(array(DB_PASSWORD>root,DB_USERNAME>root),DB);C(DB.USER_NAME,XIAOCHEN);2.一维数组C(USER_NAME,小陈…

php seaslog安装,浅谈win10下安装php seaslog扩展的方法

本篇文章给大家分享一下win10 php安装seaslog扩展的方法。有一定的参考价值&#xff0c;有需要的朋友可以参考一下&#xff0c;希望对大家有所帮助。【推荐学习&#xff1a;《PHP视频教程》】一、检查系统环境情况使用phpinfo()检查系统环境情况&#xff0c;找到需要下载的配置…

php 图片 处理,php图片处理类

本篇文章主要介绍php图片处理类&#xff0c;感兴趣的朋友参考下&#xff0c;希望对大家有所帮助。示例代码如下&#xff1a;<?php /*已知问题&#xff1a;1.在图片缩放功能中&#xff0c;使用imagecreatetruecolor函数创建画布&#xff0c;并使用透明处理算法&#xff0c;但…

php里push的用法,php array_push函数怎么用?

php array_push函数用于向数组尾部插入一个或多个元素&#xff0c;其语法是array_push(array,value1,value2...)&#xff0c;参数array必需&#xff0c;指规定一个数组&#xff1b;value1必需&#xff0c;指规定要添加的值。php array_push函数怎么用&#xff1f;定义和用法arr…

php 内容编码错误,PHP输出缓冲,ob_gzhandler引起的内容编码错误?

应用程序的输出应该只包含一个输出编码.如果您有多个编码方式不同的块,那么浏览器将得到一个无法使用的结果.因此编码错误.Kohana本身已经使用了输出缓冲区.如果你想将它与你的ob_gzhandler输出缓冲区结合起来,你需要在kohana初始化它之前启动你的缓冲区.那是因为输出缓冲区是可…

php铺满,重复铺满水印 - Jun. - OSCHINA - 中文开源技术交流社区

/*$tmp"tmp/a.jpg";$obj new WaterMask($tmp);$obj->waterImg sy_logo.png;$obj->transparent 50;$obj->output();*/class WaterMask{public $pos 0; //水印位置public $transparent 45; //水印透明度public $waterImg ; //水印图片private $srcImg …

java if (name!=null name!=),java中的NullPointerException异常

java中的NullPointerException异常关注:176 答案:3 mip版解决时间 2021-01-27 20:59提问者侢遇噹姩揂2021-01-27 02:10Login.jsp提供登录表单。到LoginCheck.jsp发生空指针异常错误。LoginCheck.jsp:String userName request.getParameter("userName");String pas…

fullcalendar php,日历插件fullcalendar+php的使用教程 — 读取json数据

根据FullCalendar日历插件说明文档中的介绍&#xff0c;日历主体事件数据的来源有三&#xff0c;一是直接以javascript数组的形式显示日历事件&#xff0c;二是获取JSON数据形式显示日历事件&#xff0c;三是函数回调的形式显示日历数据&#xff0c;三种调用数据的方式各有所用…

caany边缘检测matlab,自适应canny算法研究及其在图像边缘检测中的应用.pdf

自适应canny算法研究及其在图像边缘检测中的应用.pdf还剩51页未读&#xff0c;继续阅读下载文档到电脑&#xff0c;马上远离加班熬夜&#xff01;亲&#xff0c;很抱歉&#xff0c;此页已超出免费预览范围啦&#xff01;如果喜欢就下载吧&#xff0c;价低环保&#xff01;内容要…

flask mysql orm,flask的orm框架(Flask-SQLAlchemy)-创建表

标签&#xff1a;# 转载请留言联系ORM 是什么&#xff1f;ORM&#xff0c;Object-Relation Mapping。意思就是对象-关系映射。ORM 主要实现模型对象到关系数据库数据的映射。优点 :只需要面向对象编程, 不需要面向数据库编写代码.对数据库的操作都转化成对类属性和方法的操作.不…

Java引入依赖aar,如何将JAR依赖项包含到AAR库中

摘要&#xff1a;我有一个依赖于JAR文件的AAR文件&#xff0c;当我构建AAR项目时&#xff0c;它不包含JAR代码。细节&#xff1a;我有一个Java SDK库项目&#xff0c;其中包含我们用于JavaWeb项目的代码&#xff0c;此类库是使用Gradle内部Nexus服务器(如JAR)创建的&#xff0c…

php+使用go编译,golang如何编译

Go语言中使用 go build 命令主要用于编译代码。在包的编译过程中&#xff0c;若有必要&#xff0c;会同时编译与之相关联的包。go build 有很多种编译方法&#xff0c;如无参数编译、文件列表编译、指定包编译等&#xff0c;使用这些方法都可以输出可执行文件。go build 无参数…

php document.getel,javascript 密码强弱度检测万能插件_javascript技巧

网页密码强弱度检测请输入密码弱中强所需JS下载//checkpwd.js////*Author Netcent Aquany//*function GEId(sID){try{return document.getElementById(sID)}catch(e){};}function GetEl(szN){try{return document.getElementsByName(szN)[0]}catch(e){};}function GetElCol(szN…

session丢失php,PHP Session丢失无效问题总结

前两天玩了一下云边的轻博客,觉得东西比较小巧,自己也想弄个东西,就直接放到服务器里装了,结果啊,$_SESSION丢失了好几天&#xff5e;情况描述:$_SESSION只能在当前的访问里有效,第二次请求就像之前执行过一样,$_SESSION里的内容会没了,就一个array();下面是我对这个问题的查找…