java学习笔记 线程同步

在实现Runnable接口后,可以通过多个start方法来调用同一段代码资源,这也会导致一个问题就是资源可能不同步。

解决资源不同步的方法是,在同一时间段内,只允许一个线程来操作这个对象或方法,其他线程需等待此线程访问结束后才能继续执行,将其锁住。

关键字synchronized:表示只能有一个线程执行synchronized所声明的代码块或方法,并且在执行过程中其他方法不能锁定这个对象 。使用方式有同步代码块与同步方法,两者功能一样。

只能有一个同步方法访问该对象,其他方法若是同步的则不能访问该对象,非同步方法反而可以访问该对象(傻啦吧唧)

同步代码块

public class Test {
    public static void main(String[] args) {
          MyThread thread = new MyThread();
          Thread t1 = new Thread(thread,"t1");
          Thread t2 = new Thread(thread,"t2");
          t1.start();
          t2.start();
    }
}

class MyThread implements Runnable {
    static int num = 5;
    public void run() {
        //synchronized (this) {//表示只能有一个线程执行下面这段代码块,为下面这段代码块加锁
                if (num > 0) {
                    for (int i = 1;i < 6;i++) {
                        num--;
                        try{
                            Thread.sleep(20);//起到放大效果作用
                        }catch(InterruptedException e) {
                            System.out.println("线程休眠被打断");
                        }
                        System.out.println(Thread.currentThread().getName() + "取走还剩" + num);
                    }
                }
        //}
    }
}

使用了同步代码块之后:

同步方法进一步探讨一

public class Test {
    public static void main(String[] args) throws Exception {
          MyThread thread = new MyThread();
          Thread t1 = new Thread(thread,"t1");
          t1.start();
          Thread.sleep(10);
          thread.m2();
    }
}

class MyThread implements Runnable {
    int num = 1;

    public synchronized void run() {//仅表示锁住这个方法不能同时被其它线程执行,并不能锁住这个对象不被其他线程执行
        num = 1000;
        try{
            Thread.sleep(5000);
            System.out.println(num);
        }catch(InterruptedException e) {
            System.out.println("休眠中被打断");
        }
    }

    void m2() {
        num = 2000;
        System.out.println(num);
    }
}

结果

讨论二

public class Test {
    public static void main(String[] args) throws Exception {
          MyThread thread = new MyThread();
          Thread t1 = new Thread(thread,"t1");
          t1.start();
          Thread.sleep(10);
          thread.m2();
    }
}

class MyThread implements Runnable {
    int num = 1;

    public synchronized void run() {//仅表示锁住这个方法不能同时被其它线程执行,并不能锁住这个对象不被其他线程执行
        num = 1000;
        try{
            Thread.sleep(5000);
            System.out.println(num);
        }catch(InterruptedException e) {
            System.out.println("休眠中被打断");
        }
    }

    synchronized void m2() {//在run方法上锁期间其他线程运行时并不能为对象上第二把锁
        num = 2000;
        System.out.println(num);
    }
}

结果

时间: 2024-12-19 05:19:51

java学习笔记 线程同步的相关文章

多线程编程学习笔记——线程同步(三)

接上文 多线程编程学习笔记——线程同步(一) 接上文 多线程编程学习笔记——线程同步(二) 七.使用Barrier类 Barrier类用于组织多个线程及时在某个时刻会面,其提供一个回调函数,每次线程调用了SignalAndWait方法后该回调函数就会被执行. 1.代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; //

Java学习笔记---多线程同步的五种方法

一.引言 前几天面试,被大师虐残了,好多基础知识必须得重新拿起来啊.闲话不多说,进入正题. 二.为什么要线程同步 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常.举个例子,如果一个银行账户同时被两个线程操作,一个取100块,一个存钱100块.假设账户原本有0块,如果取钱线程和存钱线程同时发生,会出现什么结果呢?取钱不成功,账户余额是100.取钱成功了,账户余额是0.那到底是哪个呢?很难说清楚.因此多线程同步就

Java学习笔记----线程

继续学习----------------------------------------------------------------------- 在Java中线程指的是两件事 1)java.lang.Thread类的一个实例 2)线程的执行 一个Thread类实例只是一个对象,生死于堆上.main方法就是一个主线程 Java线程的创建与启动: 1)扩展java.lang.Thread类 2)实现java.lang.Runnable接口 实例化线程: 1)如果是扩展Thread的,直接用ne

C#学习笔记---线程同步:互斥量、信号量、读写锁、条件变量

http://www.cnblogs.com/maxupeng/archive/2011/07/21/2112282.html 一.互斥量(mutex) 互斥量本质上是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁. 对互斥量进行加锁以后,任何其它试图再次对互斥量加锁的线程将会被阻塞直到当前线程释放该互斥锁.如果释放互斥锁时有多个线程阻塞,所有在该互斥锁上的阻塞线程都会变成可运行状态,第一个变为运行状态的线程可以对互斥量加锁,其它线程将会看到互斥锁依然被锁住,只能回去再次

Java学习笔记----线程2

获取当前线程对象的方法是:Thread.currentThread(); 当线程目标的run方法结束,意味着线程完成 线程的状态: 1)新状态:线程对象已经创建,但是还没有调用start方法 2)可运行状态:start方法被调用.或者运行之后,从阻塞等待睡眠回来后. 3)运行状态:开始运行,可以看场可运行状态时运行状态的一个缓冲 4)等待睡眠阻塞 状态:冻结状态 5)死亡,run方法结束 阻止线程运行: 睡眠:Thread.sleep() 线程的优先级和线程的让步: setPriority() 

Java学习笔记——线程两种常用的创建调用方法

这是两种开发中常用的线程使用方法,匿名对象调用即可,很简单,掌握即可 <span style="font-size:18px;">class ThreadDemo { public static void main(String[] args) { new Thread() { public void run() { //coding here } }.start(); Runnable r = new Runnable() { public void run() { //

多线程编程学习笔记——线程池(一)

接上文 多线程编程学习笔记——线程同步(一) 接上文 多线程编程学习笔记——线程同步(二) 接上文 多线程编程学习笔记——线程同步(三) 创建多线程操作是非常昂贵的,所以每个运行时间非常短的操作,创建多线程进行操作,可能并不能提高效率,反而降低了效率. 如果你有非常多的执行时间非常短的操作,那么适合作用线程池来提高效率,而不是自行创建多线程. 线程池,就是我们先分配一些资源到池子里,当我们需要使用时,则从池子中获取,用完了,再放回池子里. .NET中的线程池是受CLR管理的,TheadTool类

java学习笔记14--多线程编程基础1

本文地址:http://www.cnblogs.com/archimedes/p/java-study-note14.html,转载请注明源地址. 多线程编程基础 多进程 一个独立程序的每一次运行称为一个进程,例如:用字处理软件编辑文稿时,同时打开mp3播放程序听音乐,这两个独立的程序在同时运行,称为两个进程 进程要占用相当一部分处理器时间和内存资源 进程具有独立的内存空间 通信很不方便,编程模型比较复杂 多线程 一个程序中多段代码同时并发执行,称为多线程,线程比进程开销小,协作和数据交换容易

线程异步学习(基于java学习笔记)

一 基本概念的理解 1.1线程中断方法 --interrupt() 当调用一个线程的interrupt方法时候,线程并没有真的被中断,只是对其状态改变,线程会有一个boolean变量isInterrputed.有wait sleep方法会阻塞线程. wait 和sleep方法都会使得线程挂起,阻塞.区别是wait会释放资源,而sleep方法并不会释放资源.一旦执行wait方法后,线程立即被挂起,直到有其他线程调用资源的notify方法.具体参见博客,多线程资源争用问题: http://blog.