java学习笔记(8)——多线程
进程:是一个程序在其自身的地址空间的一次执行活动。
线程:(区别于进程)线程没有独立的存储空间。
几个概念:时间片 线程 进程
能不能够用多进程代替多线程呢?
两个进程切换时要交换内存空间,而多线程切换时效率比较高,所以通常多个任务采用多线程,不要开启大量的进程。
java在语言级别提供了对多线程程序设计的支持
实现多线程程序的两种方式:
1,从Thread类继承
2,实现Runable接口
----------------------------------------------------------------------------------
package pack02;
//得到main函数的线程名
public class MultiThread {
public static void main(String[] args){
Thread thread = Thread.currentThread(); //得到当前线程
String string = thread.getName(); //得到线程名
System.out.println(string);
}
}
----------------------------------------------------------------------------------
package pack02;
//得到线程类的线程名
public class MultiThread {
public static void main(String[] args){
MyThread mt = new MyThread();
mt.start(); //启动线程
}
}
class MyThread extends Thread{ //Thread实现了Runable接口
public void run(){
System.out.println(getName()); //继承了getName()方法
}
}
----------------------------------------------------------------------------------
package pack02;
public class MultiThread {
public static void main(String[] args){
MyThread mt = new MyThread("i am thread"); //给线程命名
mt.start(); //启动线程
}
}
class MyThread extends Thread{
public MyThread(String str){ //调用有参数的构造
super(str);
}
public void run(){
System.out.println(getName()); //继承了getName()方法
}
}
----------------------------------------------------------------------------------
void setDaemon(boolean on) //后台线程
将该线程标记为守护线程或用户线程。
前台线程是可以阻止进程终止的,而后台线程在进程终止后终止。
----------------------------------------------------------------------------------
package pack02;
public class MultiThread {
public static void main(String[] args){
MyThread mt = new MyThread("i am thread");
mt.setDaemon(true); //设为后台线程
mt.start(); //启动线程
int i = 0;
while(true){
if(i++ == 10000){
break;
}
System.out.println(Thread.currentThread().getName());
}
}
}
class MyThread extends Thread{
public MyThread(String str){
super(str);
}
public void run(){
while(true){
System.out.println(getName()); //继承了getName()方法
}
}
}
-----------------------------------------------------------------------------------------
yeid()方法 :放弃自己执行的权力,让其他线程执行
------------------------------------------------------------------------------------
package pack02;
public class MultiThread {
public static void main(String[] args){
MyThread mt = new MyThread("i am thread");
mt.setDaemon(true); //设为后台线程
mt.start(); //启动线程
int i = 0;
while(true){
if(i++ == 10000){
break;
}
System.out.println(Thread.currentThread().getName());
}
}
}
class MyThread extends Thread{
public MyThread(String str){
super(str);
}
public void run(){
while(true){
System.out.println(getName()); //继承了getName()方法
yield(); //线程休眠
}
}
}
---------------------------------------------------------------------------------------
MAX_PRIORITY(10) MIN_PRIORITY(1) NORM_PRIORITY(5)设置线程的优先级
package pack02;
public class MultiThread {
public static void main(String[] args){
MyThread mt = new MyThread("i am thread");
mt.setPriority(Thread.MAX_PRIORITY);
mt.start(); //启动线程
int i = 0;
while(true){
if(i++ == 10000){
break;
}
System.out.println(Thread.currentThread().getName());
}
}
}
class MyThread extends Thread{
public MyThread(String str){
super(str);
}
public void run(){
while(true){
System.out.println(getName()); //继承了getName()方法 //线程休眠
}
}
}
--------------------------------------------------------------------------------
Java运行时系统实现了一个用于调度线程执行的线程调度器,用于确定某一时刻由哪一个线程在CPU上运行。
Java中线程是抢占式的而不需要时间片分配进程。
实现Runnable接口的好处:
1,实现接口可以实现多个接口和再继承
2,可以创建多个线程而用同一个属性(变量)
------------------------------------------------------------------------------------
package pack02;
public class MultiThread {
public static void main(String[] args){
MyThread mt = new MyThread();
new Thread(mt).start(); //线程1
new Thread(mt).start(); //线程2
new Thread(mt).start(); //线程3
new Thread(mt).start(); //线程4
int i = 0;
while(true){
System.out.println(Thread.currentThread().getName());
}
}
}
class MyThread implements Runnable{
int i = 0; //共用同一个变量
public void run(){
while(true){
System.out.println(Thread.currentThread().getName()+":"+i++); //继承了getName()方法 //线程休眠
}
}
}
------------------------------------------------------------------------------------
package pack02;
//内部内实现多线程共用一个变量
public class MultiThread {
public static void main(String[] args){
MyThread mt = new MyThread();
mt.getTread().start(); //启动线程1
mt.getTread().start(); //启动线程2
mt.getTread().start(); //启动线程3
mt.getTread().start(); //启动线程4
int i = 0;
while(true){
System.out.println(Thread.currentThread().getName());
}
}
}
class MyThread{
int i = 0; //共用同一个变量
class InnerThread extends Thread{ //写一个内部内实现多线程共用变量
public void run(){
while(true){
System.out.println(getName()+":"+i++);
}
}
}
Thread getTread(){
return new InnerThread();
}
}
--------------------------------------------------------------------------------------
package pack02;
//火车站订票系统
public class TicksSystem {
public static void main(String[] args){
SellTread st = new SellTread();
new Thread(st).start();
new Thread(st).start();
new Thread(st).start();
new Thread(st).start();
}
}
class SellTread implements Runnable{
int tickets = 100;
public void run() {
while(true){
if(tickets>0){ //这里会出现问题可能售出0,-1,-2,-3的票
try {
Thread.sleep(10); //用于测试
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"sell tickes"+tickets);
tickets--;
}
}
}
}
-----------------------------------------------------------------------------------------
线程的同步:
每一个对象都有一把锁子
同步块
-----------------------------------------------------------------------------------------
package pack02;
public class TicksSystem {
public static void main(String[] args){
SellTread st = new SellTread();
new Thread(st).start();
new Thread(st).start();
new Thread(st).start();
new Thread(st).start();
}
}
class SellTread implements Runnable{
int tickets = 100;
Object obj = new Object();
public void run() {
synchronized(obj){ //obj对象拿出了自己的锁子
while(true){
if(tickets>0){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"sell tickes"+tickets);
tickets--;
}
}
}
}
}
--------------------------------------------------------------------------------------------
同步方法
-------------------------------------------------------------------------------------------
package pack02;
public class TicksSystem {
public static void main(String[] args){
SellTread st = new SellTread();
new Thread(st).start();
new Thread(st).start();
new Thread(st).start();
new Thread(st).start();
}
}
class SellTread implements Runnable{
int tickets = 100;
public void run() {
while(true){
sell();
}
}
public synchronized void sell(){ //实际上是给this加锁
if(tickets>0){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"sell tickes"+tickets);
tickets--;
}
}
}
----------------------------------------------------------------------------------------------
每个class也有一个锁,是这个class所对应的Class对象的锁。
线程的死锁:
----------------------------------------------------------------------------------------------
package pack02;
public class TicksSystem {
public static void main(String[] args){
SellTread st = new SellTread();
new Thread(st).start();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
st.flag = true;
new Thread(st).start();
}
}
class SellTread implements Runnable{
boolean flag = false;
int tickets = 100;
Object obj = new Object();
public void run() {
if(flag == true){
sell();
}else{
while(true){
synchronized(obj){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (this) {
if(tickets>0){
System.out.println(Thread.currentThread().getName()+"sell tickes"+tickets);
tickets--;
}
}
}
}
}
}
public synchronized void sell(){
synchronized (obj) {
if(tickets>0){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"sell tickes"+tickets);
tickets--;
}
}
}
}
-------------------------------------------------------------------------------------------------
wait notify notifyAll (Object中的方法)
每一个对象除了有一个锁之外,还有一个等待队列(waitsct),当一个对象刚创建的时候,它的等待队列
是空的。
我们应该在当前线程锁住对象的锁后,去调用该对象的wait方法。
当调用对象的notify方法时,将从该对象的等待队列中删除一个任意选择的线程,这个线程将再次成为可
运行的线程。
当调用对象的notifyAll方法时,将从该对象的等待队列中删除所有等待的线程,这些线程将成为可运行的线程。
wait和notify主要用于producer-consumer这种关系中。
------------------------------------------------------------------------------------------------
package test;
//生产者是一个对象
//消费者是个对象
//中转站是个对象
//wait 和 notify 必须放在同步块中或同步方法中(必须是同一个对象)
//该例子中调用的都是this对象的wait和notify方法
public class Test {
public static void main(String[] args){
Queue queue = new Queue();
Producer p = new Producer(queue);
Consumer c = new Consumer(queue);
p.start();
c.start();
}
}
class Producer extends Thread{ //生产者
Queue q;
public Producer(Queue q) {
this.q = q;
}
public void run(){
for(int i=0;i<10;i++){
System.out.println("Producer put" + i);
q.put(i);
}
}
}
class Consumer extends Thread{ //消费者
Queue q;
public Consumer(Queue q){
this.q = q;
}
public void run(){
while(true){
System.out.println("Consumer get" + q.get());
}
}
}
class Queue{ //中专站
int value;
boolean bFull = false;
public synchronized void put(int i){ //this对象的监视器
if(!bFull){ //没有数据
value = i; //放置数据
bFull = true; //放过数据
notify(); //通知消费者获取数据
}
try {
wait(); //等待消费者获取数据
} catch (InterruptedException e){
e.printStackTrace();
}
}
public synchronized int get(){
if(!bFull){ //没有数据
try {
wait(); //等待放数据
} catch (InterruptedException e) {
e.printStackTrace();
}
}
bFull = false; //有数据
notify(); //通知生产者继续放置数据
return value; //得到数据
}
}
--------------------------------------------------------------------------------------------
线程的状态:
New--------->Runnable-------slep,wait,suspend,I/O阻塞------------------>Not Runnable
<------------sleep结束,notify,resume,I/O操作完成---
终止线程的方法:
设置一个flag变量终止线程。
interrupt()方法
----------------------------------------------------------------------------------------------
package test;
public class Test{
public static void main(String[] args) {
Thread1 t1 = new Thread1();
t1.start();
int index = 0;
while(true){
if(index++ == 500){
t1.stopThread();
t1.interrupt();
break;
}
System.out.println(Thread.currentThread().getName()+index);
}
System.out.println("main exit");
}
}
class Thread1 extends Thread{
private boolean bStop = false;
public synchronized void run(){
while(!bStop){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
if(bStop) return;
}
System.out.println(getName());
}
}
public void stopThread(){
bStop = true;
}
}
------------------------------------------------------------------------------------------
java的语言规范:
http://java.sun.com/docs/books/jls/second_edition/html/jTOC.doc.html
java学习笔记(8)——多线程的更多相关文章
- 【原】Java学习笔记032 - 多线程
package cn.temptation; public class Sample01 { public static void main(String[] args) { /* * [进程]:正在 ...
- Java学习笔记之——多线程
多线程编程 程序: 进程:一个程序运行就会产生一个进程 线程:进程的执行流程,一个进程至少有一个线程,称为主线程 如:QQ聊着天,同时在听音乐 一个进程可以有多个线程,多个线程共享同一个进程的资源 线 ...
- Java学习笔记:多线程(一)
Java中线程的五种状态: 新建状态(New) 就绪状态(Runnable) 运行状态(Running) 阻塞状态(Blocked) 凋亡状态(Dead) 其中阻塞状态(Blocked)又分为三种: ...
- java学习笔记(5)多线程
一.简介(过段时间再写,多线程难度有点大) --------------------------------------- 1.进程:运行时的概念,运行的应用程序 2.线程:应用程序内部并发执行的代码 ...
- Java 学习笔记(11)——多线程
Java内部提供了针对多线程的支持,线程是CPU执行的最小单位,在多核CPU中使用多线程,能够做到多个任务并行执行,提高效率. 使用多线程的方法 创建Thread类的子类,并重写run方法,在需要启动 ...
- Java学习笔记:多线程(二)
与线程生命周期相关的方法: sleep 调用sleep方法会进入计时等待状态,等待时间到了,进入就绪状态. yield 调用yield方法会让别的线程执行,但是不确保真正让出.较少使用,官方注释都说 ...
- 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁
什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...
- Java学习笔记-多线程-创建线程的方式
创建线程 创建线程的方式: 继承java.lang.Thread 实现java.lang.Runnable接口 所有的线程对象都是Thead及其子类的实例 每个线程完成一定的任务,其实就是一段顺序执行 ...
- 《Java学习笔记(第8版)》学习指导
<Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...
- 20145330第六周《Java学习笔记》
20145330第六周<Java学习笔记> . 这周算是很忙碌的一周.因为第六周陆续很多实验都开始进行,开始要准备和预习的科目日渐增多,对Java分配的时间不知不觉就减少了,然而第十和十一 ...
随机推荐
- jQuery和CSS3炫酷GOOGLE样式的用户登录界面
这是一款使用jQuery和CSS3打造的GOOGLE样式的用户登录界面特效.该登录界面特效中,右上角的小问号和错误提示小图标使用SVG来制作.username和password输入框採用浮动标签特效. ...
- C标签的使用.md
<c:set> 设置变量 <c:set var="a" scope="request" value="${'www'}"/ ...
- windows go 安装
go的安装很简单,下载go的msi文件 这里提供go1.9的msi下载链接 https://www.lanzous.com/i2gb54d 直接全部next就行,默认安装在了c盘的go 然后配置环境变 ...
- php 随机数中奖demo演示
感谢https://blog.csdn.net/z960339491/article/details/69511491提供的思路,应该是java,于我不合适,写了php <?php // 中奖概 ...
- 手把手生成决策树(dicision tree)
手把手生成决策树(dicision tree) 标签: Python 机器学习 主要參考资料: Peter HARRINGTON.机器学习实战[M].李锐,李鹏,曲亚东,王斌译.北京:人民邮电出版社, ...
- ios开发网络学习:一:NSURLConnection发送GET,POST请求
#import "ViewController.h" @interface ViewController ()<NSURLConnectionDataDelegate> ...
- com.octo.captcha.service.CaptchaServiceException: Invalid ID, could not validate unexisting o
<p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"& ...
- 新版Sublime text3注册码被移除的解决办法
Sublime Text是风靡世界的文本编辑器,支持多种编程语言,启动时间短,打开文件速度快,插件丰富,让很多程序员爱不释手.但是,对于未注册的Sublime Text, 经常在保存的时候会弹出一个烦 ...
- Log4erl
http://developerworks.github.io/2011/05/16/erlang-use-log4erl/ Erlang 使用Log4erl all = debug < inf ...
- [转至云风的博客]谈谈陌陌争霸在数据库方面踩过的坑( Redis 篇)
« 谈谈陌陌争霸在数据库方面踩过的坑(芒果篇) | 返回首页 | linode 广告时间 » 谈谈陌陌争霸在数据库方面踩过的坑( Redis 篇) 注:陌陌争霸的数据库部分我没有参与具体设计,只是参与 ...