主要内容

1.理解线程的并发性

2.线程的同步

3.线程的常用方法

  上一章中由于线程的并发性导致了多线程的执行总是会出现一些问题。。线程的并发性是程序员不可控制

的,也是不可避免的,线程的并发性往往会导致问题的出现。。那么我们为什么要控制线程的并发性呢?

如说:一个公子管理负责人正在修改雇员的工资表,而一些雇员正在领取工资,如果允许这样做必然会造成

混乱,因此,工资管理负责人正在修改工资表的时候,不允许任何的雇员领取工资,也就是说雇员们必须执行

等待状态。。

public class tickets {
public static void main(String[] args) {
sel s=new sel();
Thread t1=new Thread(s);
Thread t2=new Thread(s);
Thread t3=new Thread(s);
t1.start();
t2.start();
t3.start();
} }
class sel implements Runnable
{
private int num=100;
public void run()
{
while(true)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(num>0)
{
System.out.println(Thread.currentThread().getName()+"正在出售第"+num+"张票"+num--);
}else
{
break;
}
}
}
}

依然是卖票问题,上述的线程由于线程的并发性而导致了卖票窗口出现了问题。。

为了解决这一问题,我们引入线程的同步。。

2.线程的同步

 何为同步:我的理解就是:上述有三个线程,当t1线程启动的时候调用run()方法,那么同步函数也就起了作用,当t1执行run()

方法时,CPU分配给t1线程一把钥匙(并且只有一把),拿到这个钥匙之后开启synchronized函数的锁,然后进去执行里面的方法,

同时拿着钥匙,然后把门锁上,其他线程想访问这个函数的时候CPU没有钥匙,钥匙被线程t1拿进去了,所以其他的线程只能在线程池

中进行排队等待,当t1执行完毕后,把门打开,然后将钥匙还给CPU,然后t1线程或者消亡,或者进入阻塞状态,或者执行其他的过程

然后CPU再次把钥匙给在线程池中排队等待的线程,依次类推。。

(1)synchronized 同步函数

(2)synchronized 同步代码块

同步函数:

public class tickets {
public static void main(String[] args) {
sel s=new sel();
Thread t1=new Thread(s);
Thread t2=new Thread(s);
Thread t3=new Thread(s);
t1.start();
t2.start();
t3.start();
} }
class sel implements Runnable
{
private int num=100;
public synchronized void run()//同步函数的建立
{
while(true)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(num>0)
{
System.out.println(Thread.currentThread().getName()+"正在出售第"+num+"张票"+num--);
}else
{
break;
}
}
}
}

那么上面卖票中出现的问题就得到了解决,就不会出现一张票被卖多次,或者是出现卖第0张票的可能了。。

同步代码块:

public class tickets {
public static void main(String[] args) {
sel s=new sel();
Thread t1=new Thread(s);
Thread t2=new Thread(s);
Thread t3=new Thread(s);
t1.start();
t2.start();
t3.start();
} }
class sel implements Runnable
{
private int num=100;
public void run()//同步代码块的建立
{
synchronized(this)
{
while(true)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(num>0)
{
System.out.println(Thread.currentThread().getName()+"正在出售第"+num+"张票"+num--);
}else
{
break;
}
}
}
}
}

同步代码块的实现也可以避免线程的并发性,并且同步代码块比同步函数更具有优势,同步代码块的

效率也是比同步函数要高的。最重要的是同步代码块的好处在于:

      同步函数的锁只能是this,而同步代码块可以是任意一个obj对象,可以定义自己的类来定义自己的锁

同步代码块的速度也是比同步函数要更加快一些,应用的更加的广泛。。因此,在处理多线程安全问题的时候

最好使用同步代码块。。

  线程的常用方法

  1.start() 2.run() 3.sleep()4.isAlive()5.currentThread()6.interrupt()

前面的三个就不在进行介绍了。想必学习到了线程就知道这三个方法是什么意思了,isAlive()方法是判断

当前线程是否还活着。。currentThread()方法是获取当前执行线程的对象名,interrupt()方法是唤醒

休眠的线程。。下面举个例子。。。

/*
* 比如说张小帅正在睡觉,那么正是上课时间
* 张小帅睡觉线程正在执行,但是在上课时的
* 老师这个线程看到了张小帅睡觉线程,然后
* 直接叫醒了张小帅线程。。。
* */
public class Demo_1_1 {
public static void main(String[] args) {
ClassRoom room=new ClassRoom();
room.students.start();
room.teacher.start();
}
}
class ClassRoom implements Runnable
{
Thread students,teacher;
ClassRoom()
{
teacher=new Thread(this);
students=new Thread(this);
teacher.setName("张老师");
students.setName("张小帅");
}
public void run()
{
if(Thread.currentThread()==students)
{
System.out.println(Thread.currentThread().getName()+"正在睡觉,不听课");
try {
Thread.sleep(1000*60*60);
} catch (InterruptedException e) {
System.out.println(students.getName()+"被唤醒");
}
System.out.println("开始听课");
}
else if(Thread.currentThread()==teacher)
{
for(int i=1;i<=3;i++)
{
System.out.println("上课");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
students.interrupt();
}
}
}

顺便提一嘴。。一个已经运行的线程在没有进入死亡状态时,不要再次分配实体,由于线程的分配只能引用

最后一个实体,那么先前的实体就会成为垃圾,并且垃圾回收站不会去进行回收,因为JVM会认为那个垃圾

实体正在运行,如果突然使其中断,那么必然会导致设备的损坏。。。

比如说:

Thread thread=new Thread(target);

thread.start();

如果再次执行下面的语句。。。

thread=new Thread(target);那么原本的实体就会成为垃圾。。。

就好比下面这样。。。。


因此在写多线程的时候一定要避免这样的问题发生。。。

        

 

JAVA 多线程机制(二)的更多相关文章

  1. 简述Java多线程(二)

    Java多线程(二) 线程优先级 Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照优先级决定应该调度哪个线程来执行. 优先级高的不一定先执行,大多数情况是这样的. 优 ...

  2. Java多线程(二)关于多线程的CPU密集型和IO密集型这件事

    点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更新中~ 正式篇: Java多线程(一) 什么是线程 Java多线程(二)关于多线程的CPU密集型和IO密集型这件事 Java多线程(三)如何 ...

  3. Java多线程(二) —— 线程安全、线程同步、线程间通信(含面试题集)

    一.线程安全 多个线程在执行同一段代码的时候,每次的执行结果和单线程执行的结果都是一样的,不存在执行结果的二义性,就可以称作是线程安全的. 讲到线程安全问题,其实是指多线程环境下对共享资源的访问可能会 ...

  4. java多线程系列(二)

    对象变量的并发访问 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我 ...

  5. java多线程系列(二)---对象变量并发访问

    对象变量的并发访问 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我 ...

  6. Java总结篇系列:Java多线程(二)

    本文承接上一篇文章<Java总结篇系列:Java多线程(一)>. 四.Java多线程的阻塞状态与线程控制 上文已经提到Java阻塞的几种具体类型.下面分别看下引起Java线程阻塞的主要方法 ...

  7. java多线程基础(二)--java多线程的基本使用

    java多线程的基本使用 在java中使用多线程,是通过继承Thread这个类或者实现Runnable这个接口或者实现Callable接口来完成多线程的. 下面是很简单的例子代码: package c ...

  8. (Java多线程系列二)线程间同步

    Java多线程间同步 1.什么是线程安全 通过一个案例了解线程安全 案例:需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果. 先来看一个线程不安全的例子 class Sell ...

  9. java多线程解读二(内存篇)

    线程的内存结构图 一.主内存与工作内存 1.Java内存模型的主要目标是定义程序中各个变量的访问规则.此处的变量与Java编程时所说的变量不一样,指包括了实例字段.静态字段和构成数组对象的元素,但是不 ...

随机推荐

  1. 办公技巧:局域网内设置固定ip

    第一步:查看自己现在的网络配置 打开命令行,输入:ipconfig /all 第二步:打开控制面板 - 网络配置 根据CMD命令的ipconfig信息对号入座填入即可. 然后,重启一下WIFI即可. ...

  2. FPGA管脚约束

    Edit → language templates : 打开即可查看基本语法. 一.xilinx中的约束文件 1.约束的分类 利用FPGA进行系统设计常用的约束主要分为3类. (1)时序约束:主要用于 ...

  3. Model層資料驗證

    概述 上节我们学习了Model的数据在界面之间的传递,但是很多时候,我们在数据传递的时候为了确保数据的有效性,不得不给Model的相关属性做基本的数据验证. 本节我们就学习如何使用 System.Co ...

  4. Java:多线程,java.util.concurrent.atomic包之AtomicInteger/AtomicLong用法

    1. 背景 java.util.concurrent.atomic这个包是非常实用,解决了我们以前自己写一个同步方法来实现类似于自增长字段的问题. 在Java语言中,增量操作符(++)不是原子的,也就 ...

  5. [k8s]prometheus+alertmanager二进制安装实现简单邮件告警

    本次任务是用alertmanaer发一个报警邮件 本次环境采用二进制普罗组件 本次准备监控一个节点的内存,当使用率大于2%时候(测试),发邮件报警. k8s集群使用普罗官方文档 环境准备 下载二进制h ...

  6. Oracle PLSQL Demo - 14.定义定参数的显示游标

    declare v_empno scott.emp.empno%type; v_sal scott.emp.sal%type; ) is select t.empno, t.sal from scot ...

  7. 【转帖】漫话C++0x(四) —- function, bind和lambda

    实在是觉得此文总是去翻感觉不太好.于是果断转过来了,想看原文的请戳:http://www.wuzesheng.com/?p=2032 本文是C++0x系列的第四篇,主要是内容是C++0x中新增的lam ...

  8. Maven工程pom.xml文件秒变gradle工程的命令

    下面是一个maven工程,我想把它转成gradle项目,怎么办? 打开cmd命令行窗口,切换到你的maven工程的pom.xml文件所在目录,然后执行如下命令: gradle init --type ...

  9. GPIO实验(二)

    =============第三个实验============用c语言轮流点亮3个LED=================== 1.crt0.S.text.global _start_start:    ...

  10. 1.2.1 工作流管理系统参考模型 (zhuan)

    http://book.51cto.com/art/201009/228705.htm ************************************************* <jB ...