java线程的同步

问题的引出

在java语言中,我们常常会用到多线程相关的操作,但是多线程操作中可能会出现一些问题。

现在给定一个抢票的多线程代码

class MyThread implements Runnable{

    int a = 10;//票数

    @Override

    public void run()

    {

        while(true)

        {

            if(a>0)

            {

                try {

                    Thread.sleep(1000);

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

                System.out.println(Thread.currentThread().getName()+"买票。剩余票数"+ --a);

            }

            else

            {

                System.out.println("票卖光了");

                break;

            }

        }

    }

}

public class TheadOperation {

    public static void main(String[] args) throws InterruptedException {

        MyThread mt = new MyThread();

        new Thread( mt,"a1").start();

        new Thread(mt,"a2").start();

        new Thread( mt,"a3").start();

    }

}

这个代码通过a1,a2,a3三个线程来执行抢票的工作,但是当票数为1的时候,三个线程同时可以进入售票过程,--a会被执行,所以最终的票数将变成-2,这就是一个严重的错误,所以就需要线程同步了。

什么是线程同步?

首先,什么是线程同步?百度百科的回答是:即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作, 其他线程才能对该内存地址进行操作,而其他线程又处于等待状态,实现线程同步的方法有很多,临界区对象就是其中一种。

通俗的来说就是多个操作在同一时间内,只能有一个线程进行,其他的线程要等此线程执行完了之后才可以继续执行。

线程同步

通过关键字synchronized来实现线程同步。

可以有两种方法,一种是代码块形式,一种是关键字修饰方法的形式。

首先给出代码块形式:

 1 class MyThread implements Runnable{
 2     int a = 1000000;
 3     @Override
 4     public void run()
 5     {
 6         while(true)
 7         {
 8             synchronized(this)
 9             {
10                 if(a>0)
11                 {
12                     try {
13                         Thread.sleep(1);
14                     } catch (InterruptedException e) {
15                         e.printStackTrace();
16                     }
17                     System.out.println(Thread.currentThread().getName()+"买票。剩余票数"+ --a);
18                 }
19                 else
20                 {
21                     System.out.println("票卖光了");
22                     break;
23                 }
24             }
25         }
26     }
27 }

public class TheadOperation {
    public static void main(String[]
args) throws InterruptedException {
        MyThread mt = new MyThread();
        new Thread(
mt,"a1").start();
        new
Thread(mt,"a2").start();
        new Thread(
mt,"a3").start();
    }
}

synchronized(同步对象){代码操作}

通过该操作,就完成了将代码块中的内容线程同步。

然后是修饰方法:

class MyThread implements Runnable{

    int a = 10000;

    public synchronized boolean abc()

    {

        if(a>0)

        {

            try {

                Thread.sleep(1);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

            System.out.println(Thread.currentThread().getName()+"买票。剩余票数"+ --a);

            return true;

        }

        else

        {

            System.out.println("票卖光了");

            return false;

        }

    }

    @Override

    public void run()

    {

        while(abc())

        {

        }

    }

}

public class TheadOperation {

    public static void main(String[] args) throws InterruptedException {

        MyThread mt = new MyThread();

        new Thread( mt,"a1").start();

        new Thread(mt,"a2").start();

        new Thread( mt,"a3").start();

    }

}

通过如此也可以实现方法体内线程同步。

由于线程同步导致同一时间内只有一个线程可进行操作,其带来的一个问题就是开销大,会影响程序的性能,所以要谨慎使用。

原文地址:https://www.cnblogs.com/wu199723/p/12219573.html

时间: 2024-08-05 01:24:22

java线程的同步的相关文章

Java线程与同步

手机平台的自动化测试工具很多,之前研究过了安卓和苹果的原生自动化测试框架,经一些同事介绍,貌似Appium是个不错的工具. 想记录一下研究的结果,也算是篇干货的文章 在网上也看了一些视频,个人认为这个自动化测试的特点就是 1. 多编程语言支持 相对于传统的IOS UIautomation只能支持js语言,Appium起到了一个翻译的作用,它其实是一个CS架构,服务器和IOS模拟器或真机直接通讯,客户端和服务器之间用HTTP协议进行交互,所以客户端用什么语言其实不重要.下面会有一个python编程

Java线程:同步

一 同步的概念 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 例如:两个线程ThreadA.ThreadB都操作同一个对象Foo对象,并修改Foo对象上的数据. MyRunnable.java 1 package Thread; 2 public class MyRunnable implements Runnable{ 3 private Foo foo=new Foo(); 4 public static void main(String[] args){ 5 MyRu

java线程(2)--同步和锁

参考转载:http://rainyear.iteye.com/blog/1734311 http://turandot.iteye.com/blog/1704027 http://www.cnblogs.com/fguozhu/articles/2657904.html http://lavasoft.blog.51cto.com/62575/99155 1.线程的内存模型 Java作为平台无关性语言,JLS(Java语言规范)定义了一个统一的内存管理模型JMM(Java Memory Mode

Java深度历险(三)——Java线程?:基本概念、可见性与同步

开发高性能并发应用不是一件容易的事情.这类应用的例子包括高性能Web服务器.游戏服务器和搜索引擎爬虫等.这样的应用可能需要同时处理成千上万个请求.对于这样的应用,一般采用多线程或事件驱动的架构.对于Java来说,在语言内部提供了线程的支持.但是Java的多线程应用开发会遇到很多问题.首先是很难编写正确,其次是很难测试是否正确,最后是出现问题时很难调试.一个多线程应用可能运行了好几天都没问题,然后突然就出现了问题,之后却又无法再次重现出来.如果在正确性之外,还需要考虑应用的吞吐量和性能优化的话,就

Java 线程?基本概念 可见性 同步

开发高性能并发应用不是一件容易的事情.这类应用的例子包括高性能Web服务器.游戏服务器和搜索引擎爬虫等.这样的应用可能需要同时处理成千上万个请求.对于这样的应用,一般采用多线程或事件驱动的架构.对于Java来说,在语言内部提供了线程的支持.但是Java的多线程应用开发会遇到很多问题.首先是很难编写正确,其次是很难测试是否正确,最后是出现问题时很难调试.一个多线程应用可能运行了好几天都没问题,然后突然就出现了问题,之后却又无法再次重现出来.如果在正确性之外,还需要考虑应用的吞吐量和性能优化的话,就

基于 JVMTI 实现 Java 线程的监控(转)

随着多核 CPU 的日益普及,越来越多的 Java 应用程序使用多线程并行计算来充分发挥整个系统的性能.多线程的使用也给应用程序开发人员带来了巨大的挑战,不正确地使用多线程可能造成线程死锁或资源竞争,导致系统瘫痪.因此,需要一种运行时线程监控工具来帮助开发人员诊断和跟踪 Java 线程状态的切换.JDK 1.5 及其后续版本提供了监控虚拟机运行状态的接口 JVMTI.本文深入分析了 JVM 中的 Java 线程模型,设计了用于监控线程状态切换的模型,并基于 JVMTI 实现了对 Java 线程切

Java 线程同步

Java 线程同步根本上是要符合一个逻辑:加锁------>修改------>释放锁 1.同步代码块 示例如下: public class SyncBlock { static class DataWrap { int i; } static class SyncBlockThread extends Thread { private DataWrap date; public SyncBlockThread(DataWrap dataWrap) { this.date = dataWrap;

Java线程:线程的同步与锁

一.同步问题提出 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 例如:两个线程ThreadA.ThreadB都操作同一个对象Foo对象,并修改Foo对象上的数据. public class Foo {     private int x = 100; public int getX() {         return x;     } public int fix(int y) {         x = x - y;         return x;     } }

Java并发编程:线程的同步

.title { text-align: center } .todo { font-family: monospace; color: red } .done { color: green } .tag { background-color: #eee; font-family: monospace; padding: 2px; font-size: 80%; font-weight: normal } .timestamp { color: #bebebe } .timestamp-kwd