线程是比进程更小的执行单位,是在进程基础上进行的进一步划分。所谓多线程是指进程在执行过程中可以产生多个同时存在、同时运行的线程。多进程机制可以合理利用资源,提高程序的运行效率。一个进程至少包含一个线程(JVM虚拟机的启动是多线程的,至少有两个线程:main 和垃圾回收机制)。

1、什么是线程安全?

进程在运行时为了更好的利用资源提高运行效率,会产生多个线程,但是这多个线程运行时,会对同一个资源同时进行操作,也称之为线程异步,例如:线程A,B在对同一个链表进行操作时,如果出现了A对链表进行读取的同时,线程B同时对其进行写入数据。显然这样是非常不好的。那么就需要线程同步。

2、何为线程同步?

线程同步:通俗而言就是,当线程A在对某一资源进行操作时,那么线程B以及其他线程就必须等待,此时不能对这一资源进行操作。即线程A、B按照预定的计划对这一资源进行非同时访问。

3、线程安全:对于线程异步,这样的线程在运行时是不安全的,所以就引进同步。

//java中实现多线程有两种方法,继承自Thread类,实现Runnable接口。
//1 继承自Thread接口需要实现run方法,
public class  ThreadDemo extends Thread{
    private String name;
    public ThreadDemo(String name){
        this.name=name;
    }
    //重写Thread类中的run方法
    public void run(){
        for(int i=0;i<=10;i++){
            System.out.println(name+"运行i="+i);
        }
    }
    public static void main(String [] name){
        new ThreadDemo("线程A").start();
        new ThreadDemo("线程B").start();
    }
}
结果证明:线程A,B交错运行。

public class RunnableDemo implements Runnable{
    private String name;
    public RunnableDemo(String name){
        this.name=name;
    }
    @Override
    public void run() {
        for(int i=1;i<=15;i++){
            System.out.println(name+"运行i="+i);
        }
        
    }  
    public static void main(String [] args){
        RunnableDemo demo1=new RunnableDemo("线程A");
        RunnableDemo demo2=new RunnableDemo("线程B");
        Thread thread1=new Thread(demo1);//实例化Thread类
        Thread thread2=new Thread(demo2);//实例化Thread类
        thread1.start();//启动线程
        thread2.start();//启动线程
    }
}
//注意启动多线程必须使用Thread类实现

Thread类与Runnable接口的区别,如果继承自Thread类,不适合多个线程共享资源,而实现了Runnable接口可以方便的实现资源共享。

public class ThreadDemo2 extends Thread{
    private String name;
    private int ticket=15;
    public void run(){
        for(int i=0;i<=15;i++){
            if(ticket>0){
                System.out.println(name+"卖票:ticket="+ticket--);
            }
        }
    }
    public ThreadDemo2(String name){
        this.name=name;
    }
    public static void main(String[] args){
        ThreadDemo2 demo1=new ThreadDemo2("线程A");
        ThreadDemo2 demo2=new ThreadDemo2("线程B");
        ThreadDemo2 demo3=new ThreadDemo2("线程C");
        new Thread(demo1).start();
        new Thread(demo2).start();
        new Thread(demo3).start();
    }
}
//结果证明线程A,B,C都各自卖出15张票

public class RunnableDemo2 implements Runnable{
   private int ticket=10;
    
    public void run() {
        for(int i=1;i<=5;i++){
            if(ticket>0){
                System.out.println("卖票:ticket="+ticket--);
            }
        }        
    }
    public static void main(String[] args) {
        RunnableDemo2 demo1=new RunnableDemo2();
        new Thread(demo1).start();
        new Thread(demo1).start();
        new Thread(demo1).start();
    }
}
//结果如下:卖票:ticket=10
卖票:ticket=9
卖票:ticket=8
卖票:ticket=7
卖票:ticket=6
卖票:ticket=5
卖票:ticket=4
卖票:ticket=3
卖票:ticket=2
卖票:ticket=1

实现Runnable接口与继承自Thread类在实现多线程中相比具备以下优势

(1) 适合多个具有相同程序代码的线程处理同一资源

(2)避免java单继承特征带来的局限

(3)代码能够被多个线程共享且数据独立存在,从而增强了程序的健壮性。

4、线程同步

同步是指同一时间段内只能运行一个线程,其他线程需要等待此线程完成后才可继续执行。同步可以解决线程中资源共享的安全问题,主要有同步代码块和同步方法两种方式完成。

1)同步代码块格式

synchronized(同步对象){

需要同步的代码块

}

public class SynchronizedDemo implements Runnable{
    private int ticket=5;
    public void run() {
        for(int i=1;i<=5;i++){
            synchronized (this) {
                if(ticket>0){
                    try{
                        Thread.sleep(1000);
                    }catch(Exception e){
                        e.printStackTrace();
                    }
                    System.out.println("卖票:ticket="+ticket--);
                }
                
            }
        }        
    }
    public static void main(String[] args) {
        SynchronizedDemo demo1=new SynchronizedDemo();
        new Thread(demo1).start();
        new Thread(demo1).start();
        new Thread(demo1).start();
    }
}

结果如下:

卖票:ticket=5
卖票:ticket=4
卖票:ticket=3
卖票:ticket=2
卖票:ticket=1

如果没有加入线程同步方法,则卖票会出现负数

另外有同步方法

格式如下:

synchronized 方法返回类型方法名称(参数列表){

}

5、线程的生命周期/

1)创建状态

2)就绪状态

3)运行状态

4)阻塞状态

5)终止状态

6、加入js的理解

先看一段代码

var x = document.getElementsByName(data);
var i;
for (i = 0; i < x.length; i++) {
var value=x[i].id;
$.getJSON(ctx + '/sys/dict/description', {
value: value
}, function (data) {
var str = '&nbsp;<img src="/static/images/toolbox/description.png" title="'+data.value+'"/>';
$('.tooltip-description [desc='+value+']').append(str);
});

本段代码的意图是根据元素名取得页面上所有元素,然后逐个发送请求到后台,将根据该得到的数据在页面上进行展示,代码中,for循环应是一个原子操作,但$.getJSON()是异步请求数据,第一个请求还没结束,第二个就已经开始,导致数据混乱,因此应对for循环进行修改,使其变为线程安全,具体做法是在for循环之前加一段代码:

var x = document.getElementsByName(data);
var i;
$.ajaxSettings.async = false;
for (i = 0; i < x.length; i++) {
var value=x[i].id;
$.getJSON(ctx + '/sys/dict/description', {
value: value
}, function (data) {
var str = '&nbsp;<img src="/static/images/toolbox/description.png" title="'+data.value+'"/>';
$('.tooltip-description [desc='+value+']').append(str);
});

什么是java的线程安全?同步,异步的更多相关文章

  1. Java多线程-线程的同步(同步方法)

    线程的同步是保证多线程安全访问竞争资源的一种手段.线程的同步是Java多线程编程的难点,往往开发者搞不清楚什么是竞争资源.什么时候需要考虑同步,怎么同步等等问题,当然,这些问题没有很明确的答案,但有些 ...

  2. Java多线程-线程的同步与锁

    一.同步问题提出 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏.例如:两个线程ThreadA.ThreadB都操作同一个对象Foo对象,并修改Foo对象上的数据. package ...

  3. java thread 线程锁同步,锁,通信

    12.线程同步 当多个线程访问同一个数据时,非常容易出现线程安全问题.这时候就需要用线程同步 Case:银行取钱问题,有以下步骤: A.用户输入账户.密码,系统判断是否登录成功 B.用户输入取款金额 ...

  4. Java多线程-线程的同步与锁【转】

    出处:http://www.cnblogs.com/linjiqin/p/3208843.html 一.同步问题提出 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 例如:两个线程 ...

  5. Java中线程的同步问题

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

  6. Java高并发之同步异步

    1.概念理解: 2.同步的解决方案: 1).基于代码 synchronized 关键字 修饰普通方法:作用于当前实例加锁,进入同步代码前要获得当前实例的锁. 修饰静态方法:作用于当前类对象加锁,进入同 ...

  7. 进程?线程?多线程?同步?异步?守护线程?非守护线程(用户线程)?线程的几种状态?多线程中的方法join()?

    1.进程?线程?多线程? 进程就是正在运行的程序,他是线程的集合. 线程是正在独立运行的一条执行路径. 多线程是为了提高程序的执行效率.2.同步?异步? 同步: 单线程 异步: 多线程 3.守护线程? ...

  8. js的线程和同步异步以及console.log机制

    项目上线了,闲下来就写写东西吧.积累了好多东西都没有做笔记~挑几个印象深刻的记录一下吧. js的同步异步以及单线程问题: 都知道单线程是js的一大特性.但是通常io(ajax获取服务器数据).用户/浏 ...

  9. Java多线程-线程的同步(同步代码块)

    对于同步,除了同步方法外,还可以使用同步代码块,有时候同步代码块会带来比同步方法更好的效果. 追其同步的根本的目的,是控制竞争资源的正确的访问,因此只要在访问竞争资源的时候保证同一时刻只能一个线程访问 ...

  10. [Java Performance] 线程及同步的性能之线程池/ThreadPoolExecutors/ForkJoinPool

    线程池和ThreadPoolExecutors   虽然在程序中可以直接使用Thread类型来进行线程操作,但是更多的情况是使用线程池,尤其是在Java EE应用服务器中,一般会使用若干个线程池来处理 ...

随机推荐

  1. 【leetcode】1282. Group the People Given the Group Size They Belong To

    题目如下: There are n people whose IDs go from 0 to n - 1 and each person belongs exactly to one group. ...

  2. WPF程序发布有关事项

  3. [sdoi2015]排序(搜索+剪枝优化)

    Description 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1<=i<=N),第i中 ...

  4. vue-cli3项目中引入jquery 以及如何引进bootstrap

    1.安装jquery npm install jquery --save 2.或则在package.json中指定版本号,然后运行npm install命令 "dependencies&qu ...

  5. git忽略提交:.gitignore

    在使用Git的过程中,我们喜欢有的文件比如日志,临时文件,编译的中间文件等不要提交到代码仓库,这时就要设置相应的忽略规则,来忽略这些文件的提交. Git 忽略文件提交的方法 有三种方法可以实现忽略Gi ...

  6. Thymeleaf Multiple Template Locations using Spring Boot

    1. Overview In this tutorial, we'll see how we can define multiple template locations using Thymelea ...

  7. leetcode 207课程表

    class Solution { public: bool canFinish(int numCourses, vector<vector<int>>& prerequ ...

  8. 从GoogleClusterData统计每个用户的使用率、平均每次出价

    之前将google cluster data导入了Azure上的MySQL数据库,下一步就是对这些数据进行分析, 挖掘用户的使用规律了. 首先,为了加快执行速度,对user,time等加入索引. 然后 ...

  9. Java-获取当前IP归属地

    知道IP,获取当前IP归属地的Java程序: package Main; import java.io.BufferedReader; import java.io.DataOutputStream; ...

  10. 有关命令行的vue操作

    1.安装node.js ,通过node -v  和  npm -v  来查看node 和 npm 版本. 2. 安装bower,bower 可以说是(前端)包管理器 npm install bower ...