一.编写两种多线程的方法 

  (1).Thread(它是继承Runnable的子类)

class MyThread extends Thread{
private int ticket = 5;
@Override
public void run() {
for (int i=0 ; i<20;i++){
if(this.ticket>0)
System.out.println("卖出的票数为" + this.ticket--);
} }
}
public class MyClass {
// 测试静态内部类
public static void main(String[] args) {
new MyThread().start();
new MyThread().start();
new MyThread().start();
}
}

卖出的票数为5
卖出的票数为4
卖出的票数为3
卖出的票数为2
卖出的票数为1
卖出的票数为5
卖出的票数为4
卖出的票数为3
卖出的票数为2
卖出的票数为1
卖出的票数为5
卖出的票数为4
卖出的票数为3
卖出的票数为2
卖出的票数为1

  (2).继承Runnable接口的实现

class MyThread implements Runnable{
private int ticket = 5;
@Override
public void run() {
for (int i=0 ; i<20;i++){
if(this.ticket>0)
System.out.println("卖出的票数为" + this.ticket--);
} }
}
public class MyClass {
// 测试静态内部类
public static void main(String[] args) {
MyThread myThread = new MyThread();
new Thread(myThread).start();
new Thread(myThread).start();
new Thread(myThread).start();
//myThread.start();
//myThread1.start();
//myThread2.start();
}
}

  卖出的票数为4
  卖出的票数为5
  卖出的票数为2
  卖出的票数为3
  卖出的票数为1

  二、两种线程的区别

  Thread的方法:会受到单继承的局限性,且不方便表示出数据共享的概念

  Runnable的方法 :  不会受到单继承的局限性,可以方便表示出数据共享的概念

  它们最终都会调用Thread().start的方法。

    

  三、常见的线程的编写
  new Thread(new Runnable() {
  @Override
  public void run() {
  System.out.printf("这是hello world");
  }
  }).start(); 四、线程的同步和死锁
  1.线程同步的方法 : 同步代码块、同步方法
  (1).同步代码的关键字 : synchronized
class Mythread implements Runnable{
private int ticket = 8 ;
@Override
public void run() {
for(int i = 0; i<20; i++) {
synchronized (this) {
if (this.ticket > 0) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("剩余的票数" + this.ticket--);
}
}
}
}
}
public class MyClass {
// 测试静态内部类
public static void main(String[] args) {
Mythread mythread = new Mythread();
new Thread(mythread,"A").start();
new Thread(mythread,"B").start();
new Thread(mythread,"C").start();
new Thread(mythread,"D").start();
new Thread(mythread,"E").start();
}
} (2).代码的同步的方法:在方法上面加synchronized的关键字
class Mythread implements Runnable{
private int ticket = 8 ; @Override
public void run() {
for(int i = 0; i<20; i++) {
this.sale();
} }
public synchronized void sale(){
if (this.ticket > 0) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("剩余的票数" + this.ticket--);
}
}
}
public class MyClass {
// 测试静态内部类
public static void main(String[] args) {
Mythread mythread = new Mythread();
new Thread(mythread,"A").start();
new Thread(mythread,"B").start();
new Thread(mythread,"C").start();
new Thread(mythread,"D").start();
new Thread(mythread,"E").start();
}
} 五、线程的优先级
  Thread.setPriority(int num) : 设置线程的优先级 六、生产者和消费者
  1.解决重复的操作必须使用等待和唤醒的功能
    Object类中含有使用的关键函数
    1.等待的使用: wait()
    2.唤醒第一个: notify()
    3.唤醒全部 : notifyAll() : 谁的优先级高先执行谁
  2.生产者消费者的代码
class Message{
private String name;
private String context;
private Boolean flag = true; public synchronized void setName(String name , String context) {
if (this.flag == false){
try {
super.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name;
this.context = context; this.flag = false;
super.notify();
}
public synchronized void getName() {
if(this.flag == true){
try {
super.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(this.name + ":"+ context);
this.flag = true;
super.notify();
}
} class Product implements Runnable{
private Message message;
public Product(Message msg){
this.message = msg;
}
@Override
public void run() {
for (int i = 0;i<100;i++){
if(i % 2 == 0 ) {
message.setName("想成为","诗人");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
message.setName("不想成为","囚犯");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} }
}
}
} class Custor implements Runnable{
private Message message;
public Custor(Message msg){
this.message = msg;
}
@Override
public void run() {
for (int i = 0;i<100;i++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
message.getName(); }
}
}
public class MyClass {
// 测试静态内部类
public static void main(String[] args) {
Message message = new Message();
// Product product = new Product(message);
// Custor custor = new Custor(message);
// Thread thread1 = new Thread(product);
// Thread thread2 = new Thread(custor);
// thread1.start();
// thread2.start(); new Thread(new Product(message)).start();
new Thread(new Custor(message)).start();
}
} 七、sleep()和wait()的区别
  1.sleep() : 它是Thread的内部定义的,可以自动唤醒
  2.wait() : 它是Object的内部定义的,需要手工用notify或notifyAll唤醒
   

Java基础学习篇---------多线程的更多相关文章

  1. Java基础学习总结 -- 多线程的实现

    目录: 继承Thread类 start()方法实现多线程的原理 实现Runnable接口 Thread类 与 Runnable接口 的联系与区别 多线程的实现方法: 继承Thread类 实现Runna ...

  2. Java基础学习篇---------继承

    一.覆写(重写) 1.含义:子类的定义方法.属性和父类的定义方法.属性相同时候 方法名称相同,参数相同以及参数的个数也相同,此时为覆写(重写) 扩充知识点: 覆盖:只有属性名字和方法名字相同,类型.个 ...

  3. Java基础学习(八) - 多线程

    理解线程 进程是指一个内存中运行的应用程序,系统运行一个程序即是一个进程从创建,运行,结束的过程. 线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程. 多线程的特点是并发 ...

  4. Java基础学习篇---------this、object的学习

    一.this的学习方法 1.使用this调用构造方法市一定放在构造方法的首行 2.使用this调用构造方法时一定流出调用的出口 public class MyClass { public MyClas ...

  5. Java基础学习篇---------String、集合的学习

    一.String常用的方法: 1. == 实质比较两个对象的地址数值 String a = "hello"  (hello为匿名对象) String a1 = "hell ...

  6. Java基础学习篇---------封装

    一.类和对象分配内存 二.Java中的内部类  : 可以直接去访问外部类的所有属性(包括私有成员) 1.Java中成员内部类 (1).内部类的方法可以直接访问外部类的类中的所有成员变量 (2).外部类 ...

  7. Java基础学习篇---------static

    一.static的使用 1.使用static定义的属性往往通过类名直接调用,它的属性(方法)不属于某一个的对象的.所以对象没有创建之前就可以对static的属性的调用,方法亦如此. 2.static ...

  8. Java基础学习篇---------多态

    一.多态性的理解 1.向上转型:子类为父类对象实例化,调用的一定是子类覆写的方法,他们之间找的是共性 2.向下转型:子类扩充了父类的某些功能,而父类中没有该功能,他们之间找的是特性 案例: Numbe ...

  9. Java基础学习-- 继承 的简单总结

    代码参考:Java基础学习小记--多态 为什么要引入继承? 还是做一个媒体库,里面可以放CD,可以放DVD.如果把CD和DVD做成两个没有联系的类的话,那么在管理这个媒体库的时候,要单独做一个添加CD ...

随机推荐

  1. nginx常用配置说明

    nginx的主配置(nginx.conf)说明 #worker进程数量 worker_processes 1; #错误日志 error_log logs/error.log; #进程ID文件 pid ...

  2. 将对象转为json,加入到HttpResponseMessage中

    需要引用程序集: System.Net.Http System.Web System.Web.Extensions Code: using System; using System.Collectio ...

  3. IG—金字塔

    博客链接 选择困难症的福音--团队Scrum冲刺阶段-Day 1领航 选择困难症的福音--团队Scrum冲刺阶段-Day 2 选择困难症的福音--团队Scrum冲刺阶段-Day 3 选择困难症的福音- ...

  4. Laravel中用GuzzleHttp

    阅读数:14715 今天项目中用到GuzzleHttp,开始不知道怎么用,其实还是很简单的. 直接在项目根目录,输入以下命令 composer require guzzlehttp/guzzle 1 ...

  5. 移动文件流的读写指针---fseek

    函数原型:int fseek(FILE *stream,long offset,int origin) stream:文件指针, offset:偏移量,正数表示正向偏移,负数表示负向偏移.origin ...

  6. 创建WRAPPER时, SQL20076N 未对指定的操作启用数据库的实例。

    您可以通过运行DB2 UPDATE DBM CFG USING FEDERATED YES来设置这个参数.修改这个参数后,必须重新启动实例才会生效(DB2STOP/DB2START).所以你会出现你的 ...

  7. 2018.10.02 NOIP模拟 序列维护(线段树+广义欧拉定理)

    传送门 一道比较好的线段树. 考试时线性筛打错了于是弃疗. 60分暴力中有20分的快速幂乘爆了于是最后40分滚粗. 正解并不难想. 每次区间加打懒标记就行了. 区间查询要用到广义欧拉定理. 我们会发现 ...

  8. 2018.08.19 NOIP模拟 dp(二分+状压dp)

    Dp 题目背景 SOURCE:NOIP2015-SHY-10 题目描述 一块土地有 n 个连续的部分,用 H[1],H[2],-,H[n] 表示每个部分的最初高度.有 n 种泥土可用,他们都能覆盖连续 ...

  9. 61 origin授控于MATLAB

    官方教程:http://www.originlab.com/forum/topic.asp?TOPIC_ID=22339 学习自白东升老师originPRO8.0教程. 我用的是origin pro2 ...

  10. Nios ii调试问题集

    如果定义了一个类的.hpp,而在相应的.cpp中定义其中的函数时,根本找不到定义的类,这说明类在定义时出错,要注意类括号后的冒号. 2. 问题1:NiosII/Eclipse 中遇到“Launchin ...