多线程:

(一)进程与线程

进程特点

并发与并行的区别:

多线程编程的好处:

(二)多线程的建立

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包装来建立:

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

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

(三)线程的生命周期

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();

}

}

java多线程多态_Java学习之多线程相关推荐

  1. java中多态_java之多态

    1.多态的概述:是面向对象的三大特性之一,封装.继承.多态. ①一个具体的对象有多种形态,老虎既属于猫科动物(因为子父类是相对的,所以猫科动物也可以看做子类),又属于哺乳动物,所以老虎既可以拥有猫科动 ...

  2. android xml java混合编程_Java学习中注解与多线程,网络编程与XML技术

    本部分内容主要有集合框架及泛型,实用类,输入和输出处理,注解与多线程,网络编程与XML技术.初次学习这部分会感觉很难,主要是概念难于理解,最好是多看看例子,多练习.下面是个人的总结 拉勾IT课小编为大 ...

  3. java 并发包学习_Java学习笔记—多线程(java.util.concurrent并发包概括,转载)

    一.描述线程的类:Runable和Thread都属于java.lang包 二.内置锁synchronized属于jvm关键字,内置条件队列操作接口Object.wait()/notify()/noti ...

  4. java future用法_Java中的多线程知识点

    如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其 ...

  5. java基础线程_Java基础之多线程没那么复杂!

    多线程的引入 1.什么是多线程 线程是程序执行的一条路径,一个进程中可以包含多条线程;多线程并发执行可以提高程序的效率 2.进程和线程之间的关系 操作系统可以同时执行多个任务,每个任务就是进程;进程可 ...

  6. java多线程区别_Java中实现多线程的两种方式之间的区别

    Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线 ...

  7. java 多线程 聊天_Java做一个多线程类似于QQ的聊天程序。

    展开全部 //时间关系,粗略的做了一下,一个模拟UDP协议的测试,图标,IP,以及端口都可以设成 //发送者端的电脑参数32313133353236313431303231363533e78988e6 ...

  8. java中塑形_Java学习5——接口和多态

    1 接口 接口相当于一个完全抽象的,没有任何实现的类 所有的成员函数都是抽象函数 所有的成员变量都是public static final而且一定要赋予初值 接口中的静态函数必须有函数体 接口在声明时 ...

  9. java 多线程 迅雷_Java 仿迅雷多线程下载

    packagenet.webjoy.jackluo.android_json;/*** 1.http Range "bytes="+ start+end * 2.RandomAcc ...

最新文章

  1. python模块--如何相互调用自己写的模块
  2. Java中Scanner的使用方法
  3. tomcat5 remote debug 设置
  4. php 图片库 加星,PHP使用imagick_st类库把JPG生成GIF动画图片
  5. 模板:多项式乘法(FFTNTT)
  6. jzoj4245-er【dp,贪心】
  7. C#的protected internal
  8. AAS的完整形式是什么?
  9. java 线程池 初始大小_为什么tomcat的默认线程池大小如此之大? - java
  10. oracle安装时配饰失败了,【求助】急!!!!oracle客户端安装时创建实例失败
  11. 谷歌在外贸中的实战解析
  12. 黑马程序员-JAVA基础-IO流之字符流和字符流缓冲区
  13. 180多个web和desktop测试用例清单
  14. List数据转Map数据并进行分组排序
  15. java矩形碰撞检测_MonoGame中碰撞检测矩形的起源
  16. Android UI学习之RadioButton和RadioGroup
  17. testbench实例 vhdl_VHDL的testbench的编写
  18. 2022年华为杯中国研究生数学建模竞赛A题思路
  19. 【pnpm】pnpm : 无法加载文件 C:\Users\M_F15\AppData\Roaming\npm\pnpm.ps1
  20. 邻接矩阵(Adjacency Matrix)

热门文章

  1. 微软云打印将直接与 OneDrive 集成;全球 90 多家组织敦促苹果放弃引入”儿童安全”功能计划……...
  2. 最良心的 chrome 插件可以良心到什么程度?
  3. 要闻君说:特斯拉重磅推出影响力报告;三星官宣完成5纳米EUV工艺研发还承诺提供样品;国内首条5G智能制造生产线正式“上马”...
  4. web前端 到底怎么学?掌握什么可以拿到高薪?
  5. Cloud一分钟|茅台4.5亿入股云上贵州大数据,后者已接管苹果中国iCloud; 阿里云进入印度市场,增长速度远超当地平均水平...
  6. 互联网+2.0:技术有多强 梦想才有多近
  7. 音乐播放器 audio
  8. 用数据库修改服务器的时间格式,如何查询数据库服务器的时间格式
  9. c语言中a lt 1e-9,年9月计算机二级考试C语言强化训练题
  10. 使用react实现select_React笔记——核心概念:9.表单