先不多说,直接上个例子,著名的生产者消费者问题。

 public class ProducerConsumer {
public static void main(String[] args) {
SyncStack ss = new SyncStack();
Producer p = new Producer(ss);
Consumer c = new Consumer(ss);
new Thread(p).start();//生产者线程
new Thread(c).start();//消费者线程
}
}
/**
消费的物品---窝头
**/
class WoTou {
int id;
WoTou(int id) {
this.id = id;
}
public String toString() {
return "WoTou : " + id;
}
}
/**
消费的空间---堆栈
**/
class SyncStack {
int index = 0;
WoTou[] arrWT = new WoTou[6]; public synchronized void push(WoTou wt) {
while(index == arrWT.length) {//是while而不是if的原因,当wait被打断的时候依旧要检查下堆栈是否满了,否则,由于之前判断过index,从而会跳过判断而导致错误
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
arrWT[index] = wt;
index ++;
} public synchronized WoTou pop() {
while(index == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
index--;
return arrWT[index];
}
} /**
生产者类
**/
class Producer implements Runnable {
SyncStack ss = null;
Producer(SyncStack ss) {
this.ss = ss;
} public void run() {
for(int i=0; i<20; i++) {
WoTou wt = new WoTou(i);
ss.push(wt);
System.out.println("生产了:" + wt);
try {
Thread.sleep((int)(Math.random() * 200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
消费者类
**/
class Consumer implements Runnable {
SyncStack ss = null;
Consumer(SyncStack ss) {
this.ss = ss;
} public void run() {
for(int i=0; i<20; i++) {
WoTou wt = ss.pop();
System.out.println("消费了: " + wt);
try {
Thread.sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

效果如图:

synchronized的引入,学过数据库系统和操作系统的朋友应该会有所了解,对于共享资源,当一个线程占用的时候不能被其他线程操作,和操作系统的原子操作的原理有些相似。

对于synchronized的理解:

synchronized(对象){

同步代码块

}

当是非static synchronized函数时,默认对象为this;当为是static synchronized函数时,默认为当前对象.class。

而wait,notify,notifyAll时,前面必须指定锁,即对象(原因:因为如果出现synchronized嵌套的时候会出错,这个好比一个游戏,一个锁是一组,只有在一组之内wait,notify,notifyAll有效,而对于另外一个组是无效的。)

wait的引入:例如上题堆栈中只能放6个窝头,但是当堆栈中有6个窝头的时候,生产者获得对象锁的时候就不能生产了,因此,生产者就会进入wait池,同时又会释放对象锁。

notify的引入:唤醒wait池中的一个线程(ps:只能唤醒别的线程,不能唤醒自己)

notifyall的引入:唤醒wait池中的所有线程

在最后,给大家说下wait和sleep的区别吧,个人理解:

1.wait是Object类中方法,会抛出InteruptException,sleep是Thread类中的方法,wait方法只用在获得对象锁得时候才能用,否则会抛异常;

2.wait方法会释放对象锁,但是sleep不会释放对象锁;

3.wait后的线程需要其他的线程去唤醒,但是sleep的线程在规定的时间后会自动唤醒。

java中线程同步问题的更多相关文章

  1. Java中线程同步的理解 - 其实应该叫做Java线程排队

    Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可 ...

  2. java中线程同步的理解(非常通俗易懂)

    转载至:https://blog.csdn.net/u012179540/article/details/40685207 Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运 ...

  3. JAVA中线程同步的方法(7种)汇总

    同步的方法: 一.同步方法 即有synchronized关键字修饰的方法. 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法.在调用该方法前,需要获得内置锁,否则就 ...

  4. Java中线程同步的方法

    同步方法 即有synchronized关键字修饰的方法. 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法.在调用该方法前,需要获得内置锁,否则就处于阻塞状态. 注 ...

  5. Java中线程同步的理解

    我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可能和其他线程共享一些资源, ...

  6. java中线程同步的几种方法

    1.使用synchronized关键字 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法.在调用该方法前,需要获得内置锁,否则就处于阻塞状态. 注: synchro ...

  7. Java中线程同步锁和互斥锁有啥区别?看完你还是一脸懵逼?

    首先不要钻概念牛角尖,这样没意义. 也许java语法层面包装成了sycnchronized或者明确的XXXLock,但是底层都是一样的.无非就是哪种写起来方便而已. 锁就是锁而已,避免多个线程对同一个 ...

  8. Java中线程的同步问题

    在生活中我们时常会遇到同步的问题,而且大多数的实际问题都是线程的同步问题 我这里以生活中的火车售票来进行举例: 假设现在我们总共有1000张票要进行出售,共有10个出售点,那么当售票到最后只有一张票时 ...

  9. java中线程机制

    java中线程机制,一开始我们都用的单线程.现在接触到多线程了. 多线性首先要解决的问题是:创建线程,怎么创建线程的问题: 1.线程的创建: 四种常用的实现方法 1.继承Thread. Thread是 ...

随机推荐

  1. 如何将Jenkins multiline string parameter的多行文本优雅的保存为文件

    [现象]: 使用multi-line string parameter获取的文本变量,在jenkins shell里面显示为单行文本(空格分割). [问题]:能否转换为多行文本,并存入文件. [解决方 ...

  2. c# 控制台应用程序怎么隐藏黑窗口

    class Program     {         [DllImport("user32.dll", EntryPoint = "ShowWindow",  ...

  3. ASP.NET在请求中检测到包含潜在危险的数据,因为它可能包括 HTML标记或脚本

    背景:程序迁移到新的服务器上,在程序进行修改操作时,提示包含危险数据.然而在旧服务器上却没有问题,我猜想的可能是,新服务器IIS安装的ASP.NET版本框架高于以前的IIS上的版本框架,导致web.c ...

  4. Win(Phone)10开发第(3)弹,简单的Demo程序网络请求json解析列表显示

    先分享一个由Json字符串直接生成解析对应的类的工具: jsonclassgenerator14 百度天气接口 下面是由一个小功能(又特么的是天气)的实现,记录下下UAP的流程和结构(其实跟之前一模一 ...

  5. React server rendering —— 网易美学主站同构实录

    此文已由作者张硕授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 网易美学主站在最初开发时,因为各种历史原因,引入了例如JQuery,Bootstrop,Angular, Re ...

  6. Spring boot创建定时任务

    基于spring boot的应用创建定时任务不要太简单,给一个类加上@Configuration @EnableScheduling注解,然后给该类需要定时执行的方法加上@Scheduled(cron ...

  7. CRT和EXCRT简单学习笔记

    中国剩余定理CRT 中国剩余定理是要求我们解决这样的一类问题: \[\begin{cases}x\equiv a_1\pmod {b_1} \\x\equiv a_2 \pmod{b_2}\\...\ ...

  8. 20164317《网络对抗技术》Exp2 后门原理与实践

    1.实验内容 (1)使用netcat获取主机操作Shell,cron启动 (2)使用socat获取主机操作Shell, 任务计划启动 (3)使用MSF meterpreter(或其他软件)生成可执行文 ...

  9. AndroidStudio的一些快捷键的使用

    1.返回上一次浏览快捷键的设置   https://blog.csdn.net/yingtian648/article/details/73277388 2.格式化代码的快捷键的设置      htt ...

  10. django 使用celery 实现异步任务

    celery 情景:用户发起request,并等待response返回.在本些views中,可能需要执行一段耗时的程序,那么用户就会等待很长时间,造成不好的用户体验,比如发送邮件.手机验证码等. 使用 ...