Java基础学习篇---------多线程

一.编写两种多线程的方法
(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基础学习篇---------多线程的更多相关文章
- Java基础学习总结 -- 多线程的实现
目录: 继承Thread类 start()方法实现多线程的原理 实现Runnable接口 Thread类 与 Runnable接口 的联系与区别 多线程的实现方法: 继承Thread类 实现Runna ...
- Java基础学习篇---------继承
一.覆写(重写) 1.含义:子类的定义方法.属性和父类的定义方法.属性相同时候 方法名称相同,参数相同以及参数的个数也相同,此时为覆写(重写) 扩充知识点: 覆盖:只有属性名字和方法名字相同,类型.个 ...
- Java基础学习(八) - 多线程
理解线程 进程是指一个内存中运行的应用程序,系统运行一个程序即是一个进程从创建,运行,结束的过程. 线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程. 多线程的特点是并发 ...
- Java基础学习篇---------this、object的学习
一.this的学习方法 1.使用this调用构造方法市一定放在构造方法的首行 2.使用this调用构造方法时一定流出调用的出口 public class MyClass { public MyClas ...
- Java基础学习篇---------String、集合的学习
一.String常用的方法: 1. == 实质比较两个对象的地址数值 String a = "hello" (hello为匿名对象) String a1 = "hell ...
- Java基础学习篇---------封装
一.类和对象分配内存 二.Java中的内部类 : 可以直接去访问外部类的所有属性(包括私有成员) 1.Java中成员内部类 (1).内部类的方法可以直接访问外部类的类中的所有成员变量 (2).外部类 ...
- Java基础学习篇---------static
一.static的使用 1.使用static定义的属性往往通过类名直接调用,它的属性(方法)不属于某一个的对象的.所以对象没有创建之前就可以对static的属性的调用,方法亦如此. 2.static ...
- Java基础学习篇---------多态
一.多态性的理解 1.向上转型:子类为父类对象实例化,调用的一定是子类覆写的方法,他们之间找的是共性 2.向下转型:子类扩充了父类的某些功能,而父类中没有该功能,他们之间找的是特性 案例: Numbe ...
- Java基础学习-- 继承 的简单总结
代码参考:Java基础学习小记--多态 为什么要引入继承? 还是做一个媒体库,里面可以放CD,可以放DVD.如果把CD和DVD做成两个没有联系的类的话,那么在管理这个媒体库的时候,要单独做一个添加CD ...
随机推荐
- nginx常用配置说明
nginx的主配置(nginx.conf)说明 #worker进程数量 worker_processes 1; #错误日志 error_log logs/error.log; #进程ID文件 pid ...
- 将对象转为json,加入到HttpResponseMessage中
需要引用程序集: System.Net.Http System.Web System.Web.Extensions Code: using System; using System.Collectio ...
- IG—金字塔
博客链接 选择困难症的福音--团队Scrum冲刺阶段-Day 1领航 选择困难症的福音--团队Scrum冲刺阶段-Day 2 选择困难症的福音--团队Scrum冲刺阶段-Day 3 选择困难症的福音- ...
- Laravel中用GuzzleHttp
阅读数:14715 今天项目中用到GuzzleHttp,开始不知道怎么用,其实还是很简单的. 直接在项目根目录,输入以下命令 composer require guzzlehttp/guzzle 1 ...
- 移动文件流的读写指针---fseek
函数原型:int fseek(FILE *stream,long offset,int origin) stream:文件指针, offset:偏移量,正数表示正向偏移,负数表示负向偏移.origin ...
- 创建WRAPPER时, SQL20076N 未对指定的操作启用数据库的实例。
您可以通过运行DB2 UPDATE DBM CFG USING FEDERATED YES来设置这个参数.修改这个参数后,必须重新启动实例才会生效(DB2STOP/DB2START).所以你会出现你的 ...
- 2018.10.02 NOIP模拟 序列维护(线段树+广义欧拉定理)
传送门 一道比较好的线段树. 考试时线性筛打错了于是弃疗. 60分暴力中有20分的快速幂乘爆了于是最后40分滚粗. 正解并不难想. 每次区间加打懒标记就行了. 区间查询要用到广义欧拉定理. 我们会发现 ...
- 2018.08.19 NOIP模拟 dp(二分+状压dp)
Dp 题目背景 SOURCE:NOIP2015-SHY-10 题目描述 一块土地有 n 个连续的部分,用 H[1],H[2],-,H[n] 表示每个部分的最初高度.有 n 种泥土可用,他们都能覆盖连续 ...
- 61 origin授控于MATLAB
官方教程:http://www.originlab.com/forum/topic.asp?TOPIC_ID=22339 学习自白东升老师originPRO8.0教程. 我用的是origin pro2 ...
- Nios ii调试问题集
如果定义了一个类的.hpp,而在相应的.cpp中定义其中的函数时,根本找不到定义的类,这说明类在定义时出错,要注意类括号后的冒号. 2. 问题1:NiosII/Eclipse 中遇到“Launchin ...