synchronized:代码开始上锁,代码结束时释放锁;内置锁、自动化的、效率低、扩展性不高(不够灵活);

JDK1.5并发包Lock锁 --保证线程安全问题,属于手动挡,手动开始上锁,手动释放锁,灵活性高;

Lock 接口与 synchronized 关键字的区别

Lock 接口可以尝试非阻塞地获取锁 当前线程尝试获取锁。如果这一时刻锁没有被其他线程获取到,则成功获取并持有锁。
Lock 接口能被中断地获取锁 与 synchronized 不同,获取到锁的线程能够响应中断,当获取到的锁的线程被中断时,中断异常将会被抛出,同时锁会被释放。

Lock 接口在指定的截止时间之前获取锁,如果截止时间到了依旧无法获取锁,则返回。

Lock用法:

Lock写法
Lock lock  = new ReentrantLock();
lock.lock();
try{
//可能会出现线程安全的操作
}finally{
//一定在finally中释放锁
//也不能把获取锁在try中进行,因为有可能在获取锁的时候抛出异常lock.ublock();
}
class Res{public String username;public String sex;//true 生产者等待,消费者可消费 false生产者可以生产,消费者不可消费public boolean flag=false;Lock lock=new ReentrantLock();
}
class Out extends Thread{Res res;Condition newCondition;public Out(Res res,Condition newCondition){this.res=res;this.newCondition=newCondition;}@Overridepublic void run() {//写操作int count=0;while (true){try{//防止异常后不释放锁res.lock.lock();if(res.flag){newCondition.await();//让当前线程从运行变为阻塞,并且释放所的资源}if(count==0){//偶数res.username="小明";res.sex="男";} else {//奇数res.username="小红";res.sex="女";}count=(count+1)%2;res.flag=true;newCondition.signal();} catch (Exception e){} finally {res.lock.unlock();}}}
}
class Input extends Thread{Res res;Condition newCondition;public Input(Res res,Condition newCondition){this.res=res;this.newCondition=newCondition;}@Overridepublic void run() {while (true){try{res.lock.lock();if(!res.flag){newCondition.await();//让当前线程从运行变为阻塞,并且释放所的资源}System.out.println(res.username+","+res.sex);res.flag=false;newCondition.signal();} catch (Exception e){} finally {res.lock.unlock();}}}
}
public class LockDemo {public static void main(String[] args) {Res res = new Res();Condition condition=res.lock.newCondition();Out out = new Out(res,condition);Input input = new Input(res,condition);out.start();input.start();}}

Condition用法:

Condition condition = lock.newCondition();
res. condition.await();  类似wait
res. Condition. Signal() 类似notify

多线程并发(Thread)操作同一个资源---------网站并发(多个请求同时访问一台服务)

停止线程

停止线程思路

1.  使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。

2.  使用stop方法强行终止线程;这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果(没执行完就终止没有记录上次执行点,并且不可恢复,不论你当前什么状况都给你停掉)。

3.  使用interrupt方法中断线程。

那么怎么停止线程比较合适呢?或者说怎么设计一种停止线程的方式?

class StopThreadDemo extends Thread{private volatile boolean flag=true;@Overridepublic void run() {System.out.println("子线程开始执行......");while (flag){}System.out.println("子线程执行结束......");}public void stopThread(){this.flag=false;}
}
public class StopThread {public static void main(String[] args) throws InterruptedException {StopThreadDemo stopThreadDemo=new StopThreadDemo();stopThreadDemo.start();for (int i = 0; i < 10; i++) {System.out.println("我是主线程,i:"+i);Thread.sleep(1000);if(i==6)stopThreadDemo.stopThread();}}
}

我是主线程,i:0
子线程开始执行......
我是主线程,i:1
我是主线程,i:2
我是主线程,i:3
我是主线程,i:4
我是主线程,i:5
我是主线程,i:6
我是主线程,i:7
子线程执行结束......
我是主线程,i:8
我是主线程,i:9

class StopThreadDemo extends Thread{private volatile boolean flag=true;@Overridepublic synchronized void run() {System.out.println("子线程开始执行......");while (flag){try {wait();} catch (InterruptedException e) {
//                e.printStackTrace();stopThread();}}System.out.println("子线程执行结束......");}public void stopThread(){this.flag=false;}
}
public class StopThread {public static void main(String[] args) throws InterruptedException {StopThreadDemo stopThreadDemo=new StopThreadDemo();stopThreadDemo.start();for (int i = 0; i < 10; i++) {System.out.println("我是主线程,i:"+i);Thread.sleep(1000);if(i==6) {//当前等待线程直接抛出异常stopThreadDemo.interrupt();
//                stopThreadDemo.stopThread();}}}
}
以上两种方式都可以。。。

可以看到这是一种停止线程的方式

ThreadLocal

ThreadLocal提高一个线程的局部变量,访问某个线程拥有自己局部变量。

线程1和线程2各自操作自己的副本count,互相影响。

当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

ThreadLocal的接口方法

ThreadLocal类接口很简单,只有4个方法,我们先来了解一下:

  • void set(Object value)设置当前线程的线程局部变量的值。
  • public Object get()该方法返回当前线程所对应的线程局部变量。
  • public void remove()将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。
  • protected Object initialValue()返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。

案例:创建三个线程,每个线程生成自己独立序列号。

class ResNum{public int count=0;public static ThreadLocal<Integer> threadLocal=new ThreadLocal<Integer>(){protected Integer initialValue(){return 0;}};public String getNumber(){count=threadLocal.get()+1;threadLocal.set(count);
//        count=count+1;return count+"";}
}
class LocalThreadDemo extends Thread{private ResNum resNum;public LocalThreadDemo(ResNum resNum){this.resNum=resNum;}@Overridepublic void run() {for (int i = 0; i < 3; i++) {System.out.println(getName()+","+resNum.getNumber());}}
}
public class ThreadLocalDemo {public static void main(String[] args) {ResNum resNum1=new ResNum();
//        ResNum resNum2=new ResNum();
//        ResNum resNum3=new ResNum();LocalThreadDemo t1=new LocalThreadDemo(resNum1);LocalThreadDemo t2=new LocalThreadDemo(resNum1);LocalThreadDemo t3=new LocalThreadDemo(resNum1);t1.start();t2.start();t3.start();}
}

转载于:https://www.cnblogs.com/losemyfuture/p/9375334.html

多线程之间通讯JDK1.5-Lock相关推荐

  1. Java 多线程之间通讯(面试概念解答三)

    多线程之间通讯 多线程之间如何实现通讯? wait().notify.notifyAll()方法 wait与sleep区别? JDK1.5-Lock Lock 接口与 synchronized 关键字 ...

  2. java多线程有几种实现方法_Java多线程之间实现通讯

    一.课程目标 多线程之间如何通讯 wait.notify.notifyAll()方法 lock 停止线程 守护线程 Join方法 优先级 Yield 二.多线程之间如何实现通讯 2.1 什么是多线程之 ...

  3. 【4】多线程之间实现通讯

    目录 知识点1:多线程之间如何实现通讯 1.什么是多线程之间通讯? 2.多线程之间通讯需求 3.代码实现基本实现 (1)共享资源源实体类 (2)输入线程资源 (3)输出线程 (4)运行代码 (5)解决 ...

  4. 多线程之间的通信(等待唤醒机制、Lock 及其它线程的方法)

    一.多线程之间的通信. 就是多个线程在操作同一份数据, 但是操作的方法不同. 如: 对于同一个存储块,其中有两个存储位:name   sex, 现有两个线程,一个向其中存放数据,一个打印其中的数据. ...

  5. linux多线程拷贝信号量运用于线程之间通讯遇到的printf问题

    linux多线程拷贝信号量运用于线程之间通讯遇到的printf问题 1.题目内容 使用多线程实现文件的拷贝,并使用进度条进行相应的显示 2.进度 以下代码实现了多线程完成文件的拷贝,但是在使用进度条实 ...

  6. C# 多线程控制 通讯 和切换

    一.多线程的概念  Windows是一个多任务的系统,如果你使用的是windows 2000及其以上版本,你可以通过任务管理器查看当前系统运行的程序和进程.什么是进程呢?当一个程序开始运行时,它就是一 ...

  7. 多线程之间如何实现同步?

    一.为什么会有线程安全问题? 线程安全问题一般是发生再多线程环境,当多个线程同时共享一个全局变量或静态变量做写的操作时候,可能会发生数据冲突问题,也就是线程安全问题,在读的操作不会发生数据冲突问题 下 ...

  8. C++多线程之间,线程函数启动之后,多线程依赖的启动和线程唤醒操作。

    C++多线程之间,线程函数启动之后,线程间依赖的启动和唤醒操作 一.原理分析 1. 线程依赖关系 二. 实例分析 2.1 多线程启动 2.2 多线程模式讲解 (1) 多线程开启与主线程唤醒 (2)单线 ...

  9. python 线程等待_详解python多线程之间的同步(一)

    引言: 线程之间经常需要协同工作,通过某种技术,让一个线程访问某些数据时,其它线程不能访问这些数据,直到该线程完成对数据的操作.这些技术包括临界区(Critical Section),互斥量(Mute ...

  10. Java多线程之多线程之间按顺序调用

    Java多线程之多线程之间按顺序调用 多线程之间按顺序调用,实现A->B->C 1. 要求: AA打印5次,BB打印10次,CC打印15次 接着 AA打印5次,BB打印10次,CC打印15 ...

最新文章

  1. img标签 文件不存在_HTML常用标签
  2. java实现https请求
  3. 如何判断一个元素在亿级数据中是否存在?
  4. NameError: name ‘train_test_split‘ is not defined的解决方法:
  5. ATLAS入门篇之HoverMenuExtender控件编程(2)
  6. Linux C编程一站式学习读书笔记——socket编程
  7. 从浏览器地址栏输入网址,到网页彻底打开,中间都发生了什么?
  8. Redis三种集群模式介绍
  9. LeetCode——BFS
  10. MATLAB 在图像处理和机器视觉的应用举例01 - 官网培训视频笔记(上)-- 图像分割和图像配准
  11. NetCore 统一处理 webapi 返回null 转为“”
  12. 基于差分整合移动平均自回归模型(ARIMA)的时序数据滚动预测建模与网格调参优化实战
  13. 企业级AD域管理部署实战 微软升级版MCSE MCSA必修课程 Windows Server 2016AD管理实战
  14. PROFINET IO设备的GSD文件简介
  15. 【bat命令-在for循环中赋值给局部变量后再输出变量时提示“ECHO 处于关闭状态。”或者“ECHO 处于打开状态。”】
  16. 怎样在WORD里输入国际音标
  17. PLSQL下载、安装、配置、连接详细教程
  18. eclipse快捷键介绍
  19. 查找网络上的计算机快捷键,电脑表格查找快捷键ctrl加什么(表格快捷键各种用法大全)...
  20. 光敏二极管、光电二极管判断正负

热门文章

  1. zabbix详解(二)——zabbix工作原理
  2. ansible 第三次作业
  3. 「产品经理全连接系列2」企业如何开展敏捷或DevOps的研发变革
  4. 【转载】使用 Google Guava 美化你的 Java 代码
  5. ***mysql 用一个表的一列,去更新另一表的一列
  6. 识别验证码,你有几分成功率?
  7. SQL Server 游标运用:查看所有数据库所有表大小信息(Sizes of All Tables in All Database)...
  8. ubuntu mysql远程连接
  9. java反射集合类_java反射 - lara - OSCHINA - 中文开源技术交流社区
  10. excel vba导入html表格,Excel VBA读取网址API 类Json数据并写入单元格的方法