java线程安全测试代码 java线程安全测试代码大全
Java中 synchronized没有用,代码如下。运行结果如图(不该出现非正数)。谢谢高手解答!!
package ergouge.thread.demo;
十年的鸡东网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。成都全网营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整鸡东建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联公司从事“鸡东网站设计”,“鸡东网站推广”以来,每个客户项目都认真落实执行。
/*
nbsp;多线程模拟售票:三个窗口售票20张
nbsp;*/
class Ticket implements Runnable {
nbsp;nbsp;nbsp;nbsp;private int num = 20;
nbsp;nbsp;nbsp;nbsp;final String s = "hell";
nbsp;nbsp;nbsp;nbsp;public void run() { // 覆盖run方法
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;sell();
nbsp;nbsp;nbsp;nbsp;}
nbsp;nbsp;nbsp;nbsp;// 解决线程安全
nbsp;nbsp;nbsp;nbsp;public void sell() {
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;// synchronized (new Object()) { // 同步代码块,防止多个线程进入
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;// 同步代码块,防止多个线程进入
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;while (num gt; 0) {
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;// 放到这里也不行 synchronized(new Object()) { //
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;// 同步代码块,防止多个线程进入
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;synchronized (s) {
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;try {
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;Thread.sleep(500);
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;} catch (InterruptedException e) {
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;} // 让线程sleep 0.5秒,测试线程安全问题
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;System.out.println(Thread.currentThread().getName() + "...sell ticket " + num--);
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;}
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;}
nbsp;nbsp;nbsp;nbsp;}
}
public class TicketSale {
nbsp;nbsp;nbsp;nbsp;public static void main(String[] args) {
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;Ticket x = new Ticket();
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;Thread t1 = new Thread(x);
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;Thread t2 = new Thread(x);
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;Thread t3 = new Thread(x);
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;t1.start();
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;t2.start();
nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;t3.start();
nbsp;nbsp;nbsp;nbsp;}
}
楼主你仔细看下我该了以后的代码,先找到区别
有两点楼主要注意:
一、synchronized(newObject())相当于没有同步,同步的是同一块内存地址,你这样的话,每次都不是同一块内存地址,因此相当于没有同步
二、同步的范围:同步的范围不是越大越好,仔细想想看吧楼主,你的同步范围太大了
告诉你什么是java多线程定义及线程安全
网页链接
举个简单易懂的例子,多线程相当于一条马路上的多条车道,单车道行驶车辆速度较慢,且可能产生拥堵,多车道可缓解车速、拥堵情况。
线程是指进程中的一个执行流程,一个进程中可以运行1-n个线程。也可以说是在同一个进程内又可以执行多个任务,而每一个任务我们就可以看成是一个线程。
是程序的执行单元,执行路径。是程序使用CPU的最基本的单位
如果程序只有一条执行路径,那么该程序就是单线程程序
如果程序有多条执行路径,那么该程序就是多线程程序
2、多线程的意义:
多线程不是为了提高程序的执行速度,而是为了提高程序的使用率。
多线程的执行都是为了抢占CPU的使用率。
不能保证多线程程序会在什么时候优先抢到使用权,所以线程的执行具有随机性
3、多线程的优点:
充分利用硬件资源。由于线程是cpu的基本调度单位,所以如果是单线程,那么最多只能同时在一个处理器上运行,意味着其他的CPU资源都将被浪费。而多线程可以同时在多个处理器上运行,只要各个线程间的通信设计正确,那么多线程将能充分利用处理器的资源。
多线程程序能将代码量巨大,复杂的程序分成一个个简单的功能模块,每块实现复杂程序的一部分单一功能,这将会使得程序的建模,测试更加方便,结构更加清晰,更加优雅
为了避免阻塞,单线程应用程序必须使用非阻塞I/O,这样的I/O复杂性远远高于同步I/O,并且容易出错。
4、多线程的缺点:
线程安全:由于统一进程下的多个线程是共享同样的地址空间和数据的,又由于线程执行顺序的不可预知性,一个线程可能会修改其他线程正在使用的变量,这一方面是给数据共享带来了便利;另一方面,如果处理不当,会产生脏读,幻读等问题,好在Java提供了一系列的同步机制来帮助解决这一问题,例如内置锁。
Java中如何保证线程安全性
并发(concurrency)一个并不陌生的词,简单来说,就是cpu在同一时刻执行多个任务。
而Java并发则由多线程实现的。
在jvm的世界里,线程就像不相干的平行空间,串行在虚拟机中。(当然这是比较笼统的说法,线程之间是可以交互的,他们也不一定是串行。)
多线程的存在就是压榨cpu,提高程序性能,还能减少一定的设计复杂度(用现实的时间思维设计程序)。
这么说来似乎线程就是传说中的银弹了,可事实告诉我们真正的银弹并不存在。
多线程会引出很多难以避免的问题, 如死锁,脏数据,线程管理的额外开销,等等。更大大增加了程序设计的复杂度。
但他的优点依旧不可替代。
死锁和脏数据就是典型的线程安全问题。
简单来说,线程安全就是: 在多线程环境中,能永远保证程序的正确性。
只有存在共享数据时才需要考虑线程安全问题。
java内存区域:
其中, 方法区和堆就是主要的线程共享区域。那么就是说共享对象只可能是类的属性域或静态域。
了解了线程安全问题的一些基本概念后, 我们就来说说如何解决线程安全问题。我们来从一个简单的servlet示例来分析:
public class ReqCounterServlet extends HttpServlet{ private int count = 0;
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
count++;
System.out.print("当前已达到的请求数为" + count);
}
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException { // ignore }
}
1. 了解业务场景的线程模型
这里的线程模型指的是: 在该业务场景下, 可能出现的线程调用实况。
众所周知,Servlet是被设计为单实例,在请求进入tomcat后,由Connector建立连接,再讲请求分发给内部线程池中的Processor,
此时Servlet就处于一个多线程环境。即如果存在几个请求同时访问某个servlet,就可能会有几个线程同时访问该servlet对象。如图:
线程模型,如果简单的话,就在脑海模拟一下就好了,复杂的话就可以用纸笔或其他工具画出来。
2. 找出共享对象
这里的共享对象就很明显就是ReqCounterServlet。
3. 分析共享对象的不变性条件
不变性条件,这个名词是在契约式编程的概念中的。不变性条件保证类的状态在任何功能被执行后都保持在一个可接受的状态。
这里可以引申出, 不可变对象是线程安全的。(因为不可变对象就没有不变性条件)
不变性条件则主要由对可变状态的修改与访问构成。
这里的servlet很简单, 不变性条件大致可以归纳为: 每次请求进入时count计数必须加一,且计数必须正确。
在复杂的业务中, 类的不变性条件往往很难考虑周全。设计的世界是险恶的,只能小心谨慎,用测量去证明,最大程度地减少错误出现的几率。
4. 用特定的策略解决线程安全问题。
如何解决的确是该流程的重点。目前分三种方式解决:
第一种,修改线程模型。即不在线程之间共享该状态变量。一般这个改动比较大,需要量力而行。
第二种,将对象变为不可变对象。有时候实现不了。
第三种,就比较通用了,在访问状态变量时使用同步。 synchronized和Lock都可以实现同步。简单点说,就是在你修改或访问可变状态时加锁,独占对象,让其他线程进不来。
这也算是一种线程隔离的办法。(这种方式也有不少缺点,比如说死锁,性能问题等等)
其实有一种更好的办法,就是设计线程安全类。《代码大全》就有提过,问题解决得越早,花费的代价就越小。
是的,在设计时,就考虑线程安全问题会容易的多。
首先考虑该类是否会存在于多线程环境。如果不是,则不考虑线程安全。
然后考虑该类是否能设计为不可变对象,或者事实不可变对象。如果是,则不考虑线程安全
最后,根据流程来设计线程安全类。
设计线程安全类流程:
1、找出构成对象状态的所有变量。
2、找出约束状态变量的不变性条件。
3、建立对象状态的并发访问管理策略。
有两种常用的并发访问管理策略:
1、java监视器模式。 一直使用某一对象的锁来保护某状态。
2、线程安全委托。 将类的线程安全性委托给某个或多个线程安全的状态变量。(注意多个时,这些变量必须是彼此独立,且不存在相关联的不变性条件。)
网页标题:java线程安全测试代码 java线程安全测试代码大全
分享URL:http://scyanting.com/article/hhdghc.html