/*
第五讲 多线程 了解进程和线程
在多任务系统中,每个独立执行的程序称为进程,也就是"正在进行的程序",我们现在使用的操作系统一般都是多任务的
即能够同时执行多个应用程序,实际情况是,操作系统负责对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第五节(面向对象一)

    本篇文章是<零基础学Java>专栏的第五篇文章,文章采用通俗易懂的文字.图示及代码实战,从零基础开始带大家走上高薪之路! 本文章首发于公众号[编程攻略] 类与对象 在哲学体系中,可以分为主 ...

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

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

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

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

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

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

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

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

  8. Java多线程-线程的同步(同步方法)

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

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

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

随机推荐

  1. java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest

    错误信息 查看Console标签页: 这儿提示找不到HttpServletRequest类. 解决办法 规则文件更新的时候需要调用servlet-api.jar相关的类,如果您的系统环境下无法找到这个 ...

  2. 查看sql执行的情况

    今天同事让看一个sql,无意中学到一个查看sql执行情况的命令,以前都是傻傻的等的,今后不用了 SELECT percent_complete FROM sys.dm_exec_requests

  3. 【deep learning学习笔记】注释yusugomori的DA代码 --- dA.cpp --模型准备

    辅助函数和构造函数. #include <iostream> #include <math.h> #include "dA.h" using namespa ...

  4. 生成Markdown目录 字符串解析 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  5. 文本分类(六):使用fastText对文本进行分类--小插曲

    http://blog.csdn.net/lxg0807/article/details/52960072 环境说明:python2.7.linux 自己打自己脸,目前官方的包只能在linux,mac ...

  6. 个基于TensorFlow的简单故事生成案例:带你了解LSTM

    https://medium.com/towards-data-science/lstm-by-example-using-tensorflow-feb0c1968537 在深度学习中,循环神经网络( ...

  7. 在Linux下锁住键盘和鼠标而不锁屏

    假如在你正看着屏幕上的某些重要的事情时,你不想让你的小猫或者小狗在你的键盘上行走,或者让你的孩子在键盘上瞎搞一气,那我建议你试试 xtrlock 这个工具. 假如在你正看着屏幕上的某些重要的事情时,你 ...

  8. 简单介绍Ceph分布式存储集群

    在规划Ceph分布式存储集群环境的时候,对硬件的选择很重要,这关乎整个Ceph集群的性能,下面梳理到一些硬件的选择标准,可供参考: 1)CPU选择 Ceph metadata server会动态的重新 ...

  9. JPA(四):EntityManager

    Persistence Persistence类使用于获取EntityManagerFactory实例,该类包含一个名为createEntityManagerFactory的静态方法. // 创建En ...

  10. Android Studio 上传aar(Library)到JCenter

    目的 这篇文章介绍通过Gradle把开源项目发布到公共仓库JCenter中,发布自己的android library(也就是aar)到公共的jcenter仓库. 为什么选择JCenter,因为JCen ...