主要内容

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. ubuntu中pip安装redis-py及pip的使用

    安装redis-py的前提是已经将redis成功安装,redis安装过程请看博文 ubuntu14安装redis 1.安装pip sudo apt-get install python-pip 2.使 ...

  2. mysql工作中常见问题

    1.Error Code: 1044 - Access denied for user 'root'@'localhost' to database 'information_schema'Query ...

  3. 解决maven构建webapp index.jsp报错问题

    今天早上想用maven 构建一个webapp 然后index.jsp华华丽丽的报错了  当时我的心情是一万头草泥马奔过啊,为啥你给我创建的webapp 还会报错啊!!!!!! 然后百度了一下,各种说少 ...

  4. ToDictionary的用法

    上次已经查过一次了,这次又忘了...看来有必要记录一下: linq查询结果经常ToList.ToArray什么的,但是ToDictionary用的比较少,导致经常忘记怎么用... ToDictiona ...

  5. Let's call it a "return"

    Preface Long time no see. For some reason that I failed to keep updating this blog, which is really ...

  6. C#特性Attribute学习

    起初一直纠结于如何调用特性附着在下面那个成员的值,后来发现不需要调用,通过反射加载的时候是自动绑定上去的,即 获得成员对象之后,有一个方法可以获得特性标签. 其实从类库提供者,和类库使用者的角度,分开 ...

  7. [k8s]kube-router替代kube-proxy实现svc网络和pod网络

    本文讲解了kube-router部署,无需在部署kube-proxy了. kube-router采用lvs实现svc网络,采用bgp实现pod网络. kube-router也是基于cni网络,本文是容 ...

  8. [phpcms v9]自定义表单添加验证码验证功能

    修改  \phpcms\templates\default\formguide\show.html 中添加验证码显示 <input type="text" id=" ...

  9. C#compiler

    http://www.cnblogs.com/Ninputer/archive/2011/06/12/2078671.html Compilers - Managed Profile-Guided O ...

  10. SqlServer 如何知道是否发生了索引碎片

    --如何知道是否发生了索引碎片 SELECT object_name(dt.object_id) Tablename,si.name IndexName,dt.avg_fragmentation_in ...