java第五节 多线程/多线程的同步

时间:2022-03-18 20:03:26
/*
第五讲 多线程 了解进程和线程
在多任务系统中,每个独立执行的程序称为进程,也就是"正在进行的程序",我们现在使用的操作系统一般都是多任务的
即能够同时执行多个应用程序,实际情况是,操作系统负责对CPU等设备的资源进行分配和管理,虽然这些设备某一时时刻只能做一件事
但以非常小的时候间隔交替执行多个程序,就可以给人以同时执行多个程序的感觉o 一个进程中又可以包含一个或多个线程,一个线程就是一个程序内部的一条执行线索,如果要一个程序实现多段代码同时交替执行,就需产生多个线程,并指定每个线程上所要运行的程序代码段,这就是多线程 多线程与单线程的对比
ThreadDemo1.Main() -> TestThread.run(); 单线程
ThreadDemo1.Main() -> TestThread.run(); 多线程 用Thread类创建线程
1 要将一段代码在一个新的线程上运行,该代码应该在一个类的run函数中,
并且run函数所在的类是Thread类的子类,倒过来看,我们要实现多线程,必须编写一个继承了Thread类的子类
子类要覆盖Thread类中的run函数,在子类的run函数中调用想在新线程上运行的程序代码 2 启动一个新的线程,我们不是直接调用Thread子类对象中的run()方法,而是调用Thread子类对象中的start(从Thread类的继承到的)方法
Thread类对象的Start方法将产生一个新的线程,并在该线程上运行该Thread类对象中的run方法,根据面向对象运行时的多态性,在该线程上实际运行的是Thread子类(也就是我们写的那个类)对象中的run方法 3 由于线程的代码段在run方法中,那么该方法执行完成以后线程也就相应的结束了,因而我们可以通过控制run方法中循环的条件来控制线程的结束 后台线程与联合线程
如果我们对某个线程对象在启动(调用start方法)这前调用了setDaemon(true)方法,这个线程就变成了后台线程 对java程序来说,只要不家一个前台线程在运行,这个进程就不会结束,如果一个进程中只有后台线程在运行,这个进程就会结束 pp.join()的作用是把pp所对应的线程合并到调用pp.join(); 语句的线程中 使用Runnable接口创建多线程
1 适合多个相同程序代码的线程去处理同一资源的情况,把虚拟CPU(线程)同程序的代码,数据有效分离,较好的体现了面向对象的设计思想 2 可以避免由于java的单继承特性带来的局限,我们经常碰到这样的一种情况,即当我们要将已经继承了某一个类的子类放入多线程中
由于一个类不能同时有两个父类,所以不能用继承Thread类的方式,那么,这个类就只能采用实现Runnable的方式 3 当线程被构造时,需要的代码和数据通过一个对象作为构造函数实参传递进去,这个对象就是一个实现了Runnable接口的类的实例 4 事实上,几乎所有多线程应用都可用Runnable接口方式 多线程在实际中的应用
网络聊天程序的收发
1):如果一方从键盘上读取了数据并发送给了对方,程序运行到"读取对方回送的数据"并一直等持对访回送数据
如果对方没有回应,程序不能再做任何其他事情,这时程序处于阻塞状态,即使用户想正常终止程序运行都不可能
更不能实现"再给对方发送一条信息,催促对方赶快应答"这样的事情了
2):如果程序没有事先从键盘上读取数据并向外发送,程序将一直在"从键盘上读取数据"处阻塞,即使有数据从网上发送过来,程序无法到达"读取对方回送的数据"处,程序将不能收到别外先主动发送过来的数据 表记录的复制的中途取消
www服务器为每一个来访者都建立专线服务 while(bStop)
{
get;
copy;
}
bStop = true; 多线程的同步
什么是线程安全
同步代码块
同步函数
代码块与函数间的同步
列锁问题 线程间的通信
放入新的数据前的状态 生产者准备放入的新数据
= =
= =
张三 李四
男 女 生产者已放入
生产者还没有放入
放入后的状态(消费者最终取到的数据) 李四 男 wait:告诉当前线程放弃监视器并进入睡眠状态直到其他线程进入同一监视器并调用notify为止 notify: 唤醒同一对象监视器中调用wait的第一个线程,用于类似饭馆有一个空位后通知所有待候就餐的顾客中的第一位可以入座的情况 notify All:唤醒同一对象监视器中调用wait的所有线程,具有最高优先级的线程首先被唤醒并执行,用于类似某个不定期的培训班终于招生满额了,通知所有学员都来上课的情况 */
class ThreadDemo1
{
public static void main(String[] args)
{
//new Thread().start(); //new TestThread().run();
//new TestThread().start(); //Thread tt = new TestThread();
//tt.setDaemon(true);
//tt.start(); /*Thread tt = new Thread(new TestThread());
tt.start(); int index = 0;
while(true)
{
if(index++ == 1000){
try{ tt.join(1000); }catch(Exception e){}
}
System.out.println("main() "+Thread.currentThread().getName());
}*/ /*new TestThread().start();
new TestThread().start();
new TestThread().start();
new TestThread().start();*/ /*
TestThread tt = new TestThread();
tt.start();
tt.start();
tt.start();
tt.start();*/ TestThread tt = new TestThread();
new Thread(tt).start(); try{ Thread.sleep(1);}catch(Exception e){} tt.str = new String("method");
new Thread(tt).start(); //new Thread(tt).start();
//new Thread(tt).start(); }
} //如果用多线程操作也有线程安全的问题
/*public void push(char c)
{
data[index] = c;
index++;
}*/ class TestThread implements Runnable //extends Thread
{ int tickets = 100; String str = new String(""); public void run()
{
//String str = new String(""); //不能将str对象放到run()代码块中,只能放到Thread类中才行 if(str.equals("method"))
{
while(true)
{
sale();
}
}else{
while(true)
{
//同步语句块,在同一时间段只有一个线程应用该块代码
//synchronized()后面必须跟后一个任意的对象
//str => false true, 锁其标
synchronized(str){
//synchronized(this){
if(tickets > 0){
try{
Thread.sleep(10);
}catch(Exception e){
}
//死锁
//synchronized(this){} System.out.println("run() "+Thread.currentThread().getName()+" is saling ticket " + tickets--);
}
}
}
}
}
//代码块同步函数 //同步函数, 同步对象的标志问题
public synchronized void sale()
{
if(tickets > 0){
try{
Thread.sleep(10);
}catch(Exception e){
} //死锁
//synchronized(str){} System.out.print("sale():");
System.out.println("sale run() "+Thread.currentThread().getName()+" is saling ticket " + tickets--);
}
}
};

  

/*
线程的等待和唤醒过程 Thread t Synchronized(o) 线程t 得到对象0的lock旗标 o.wiat(); 此时线程t被放置到对象o的等待线程池中,t自动释放o的锁旗标 o.notify(); 当另外的线程执行了对象o的notify()方法后,线程t可能会被从o的等待线程池中释放出来
并且移动到等待线程对象o的锁旗标的线程池中,当t得到锁旗标时就会执行下去 线程生命的控制 程序中如何控制线程的生命
//suspend; */
class Product implements Runnable
{
Q q;
public Product(Q q)
{
this.q = q;
}
public void run()
{
int i=0;
while(true)
{
/*synchronized(this.q)
{
if(this.q.bFull){
try{this.q.wait();}catch(Exception e){};
}
if(i == 0){
q.name = "zhangsan"; try{ Thread.sleep(1); }catch(Exception e){} q.sex = "male";
}else{
q.name = "lisi";
q.sex = "female";
}
this.q.bFull = true;
this.q.notify();
}*/
if(i==0){
this.q.put("zhangsan","male");
}else{
this.q.put("lisi","female");
}
i = (i+1)%2;
}
}
}; class Consumer implements Runnable
{
Q q;
public Consumer(Q q)
{
this.q = q;
}
public void run()
{
while(true)
{
/*synchronized(this.q)
{
//wait();
if(!this.q.bFull) //如果缓存内容为空,退出进行睡眠
try{this.q.wait();}catch(Exception e){};
//System.out.println("Name:"+q.name+" Sex:"+q.sex);
//this.q.get(); this.q.bFull = false;
this.q.notify();
}*/
this.q.get();
}
}
}; class Q
{
private String name = "unknown";
private String sex = "unknown"; private boolean bFull = false; public synchronized void put(String name, String sex)
{
if(this.bFull){
try{ this.wait(); }catch(Exception e){}
}
this.name =name;
try{ Thread.sleep(10); }catch(Exception e){}
this.sex = sex;
this.bFull = true;
this.notify();
} public synchronized void get()
{
if(!this.bFull){
try{ this.wait(); }catch(Exception e){}
}
System.out.println("Name:"+this.name+" Sex:"+this.sex);
this.bFull = false;
this.notify();
} }; class ThreadCommunation
{
public static void main(String []args)
{
//Q q = new Q();
//new Thread(new Product(q)).start();
//new Thread(new Consumer(q)).start(); ThreadTest tt = new ThreadTest();
new Thread(tt).start(); for(int i=0; i<100; i++)
{
if(i==50){
tt.stopMe();
}
System.out.println("main() is running i="+i); }
}
} class ThreadTest implements Runnable
{
private boolean bStop = true; public void stopMe()
{
this.bStop = false;
} public void run()
{
while(bStop)
{
System.out.println("run "+Thread.currentThread().getName()+" is running");
}
}
};

  

java第五节 多线程/多线程的同步的更多相关文章

  1. 第一百四十五节,JavaScript,同步动画

    JavaScript,同步动画 将上一节的,移动透明动画,修改成可以支持同步动画,也就是可以给这个动画方法多个动画任务,让它同时完成 原理: 向方法里添加一个属性,这个属性是一个对象,同步动画属性,属 ...

  2. Java第五节课总结

    继承是对现实生活中的“分类”概念的一种模拟. 通过surper调用的基类构造方法,必须是子类构造方法中的第一个语句. 构造函数(constructor)是一种特殊的方法 .主要用来在创建对象时初始化对 ...

  3. Java中使用CountDownLatch进行多线程同步

    CountDownLatch介绍 在前面的Java学习笔记中,总结了Java中进行多线程同步的几个方法: 1.synchronized关键字进行同步. 2.Lock锁接口及其实现类ReentrantL ...

  4. 关于Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇高质量的博文)

    Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇质量高的博文) 前言:在学习多线程时,遇到了一些问题,这里我将这些问题都分享出来,同时也分享了几篇其他博客主的博客,并且将我个人的理解也分享 ...

  5. 第九节:详细讲解Java中的泛型,多线程,网络编程

    前言 大家好,给大家带来详细讲解Java中的泛型,多线程,网络编程的概述,希望你们喜欢 泛型 泛型格式:ArrayList list= new ArrayList(); ArrayList list= ...

  6. Java:多线程,线程同步,同步锁(Lock)的使用(ReentrantLock、ReentrantReadWriteLock)

    关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象.本文探讨Lock对象. synchronize ...

  7. Java多线程-线程的同步&lpar;同步方法&rpar;

    线程的同步是保证多线程安全访问竞争资源的一种手段.线程的同步是Java多线程编程的难点,往往开发者搞不清楚什么是竞争资源.什么时候需要考虑同步,怎么同步等等问题,当然,这些问题没有很明确的答案,但有些 ...

  8. java多线程:线程同步synchronized(不同步的问题、队列与锁),死锁的产生和解决

    0.不同步的问题 并发的线程不安全问题: 多个线程同时操作同一个对象,如果控制不好,就会产生问题,叫做线程不安全. 我们来看三个比较经典的案例来说明线程不安全的问题. 0.1 订票问题 例如前面说过的 ...

  9. java面试必问:多线程的实现和同步机制,一文帮你搞定多线程编程

    前言 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进程的地址空间是互相隔离的:进程拥有各种资源和状态信息,包括打开的文件.子进程和信号处理. 线 ...

随机推荐

  1. linux故障判断

    系统问题: 带宽 netstat cpu io 磁盘 内存     free ------------------------------------------------------------- ...

  2. codevs 1488GangGang的烦恼

    题目链接:http://codevs.cn/problem/1488/ 写个高精度大数运算就行 #include<cstdio> #include<iostream> #inc ...

  3. python和pywin32实现窗口查找、遍历和点击

    Pywin32是一个Python库,为python提供访问Windows API的扩展,提供了齐全的windows常量.接口.线程以及COM机制等等. 1.通过类名和标题查找窗口句柄,并获得窗口位置和 ...

  4. java并发编程--Runnable Callable及Future

    1.Runnable Runnable是个接口,使用很简单: 1. 实现该接口并重写run方法 2. 利用该类的对象创建线程 3. 线程启动时就会自动调用该对象的run方法 通常在开发中结合Execu ...

  5. Python3学习笔记24-操作文件和目录

    环境变量 在操作系统中定义的环境变量,全部保存在os.environ这个变量中,可以直接查看: import os print(os.environ) 操作文件和目录 操作文件和目录的函数一部分放在o ...

  6. IOC入门

    Spring六大模块 1.SpringCore  spring的核心功能:IOC容器,解决对象的创建及依赖关系 2.SpringWeb   spring对Web模块的支持 3.SpringDAO  s ...

  7. SQL SERVER分区详解(1-5)

    转自: (五)SQL Server分区自动化案例     (四)SQL Server分区管理     (三)索引分区知识详解     (二)SQL Server分区创建过程     (一)SQL Se ...

  8. 深入理解 iOS Rendering Process

    本文将从 OpenGL 的角度结合 Apple 官方给出的部分资料,介绍 iOS Rendering Process 的概念及其整个底层渲染管道的各个流程. 相信在理解了 iOS Rendering ...

  9. SmartSql 动态仓储

    动态代理仓储 SmartSql源码:https://github.com/Ahoo-Wang/SmartSql 简介 动态代理仓储(SmartSql.DyRepository)组件是SmartSql非 ...

  10. 自己根据java的LinkedList源码编写的一个简单的LinkedList实现

    自己实现了一个简单的LinkedList /** * Create by andy on 2018-07-03 11:44 * 根据 {@link java.util.LinkedList}源码 写了 ...