加锁问题,必须加锁在对象上或方法上,加在基本数据类型上无效

如下代码:运行结果:

Thread-0 holds the locktrue
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at blockthread.DeadLock$Thread1.run(DeadLock.java:24)
main holds the lockfalse
Thread-0:99
Thread-1 holds the lockfalse
Thread-1:100

失败原因是: synchronized 只能同步对象或者方法,如果在基本数据类型上给它加锁,synchronized 无效。


package blockthread;

public class DeadLock {

    public static Integer i=100;

    public static void main(String[] args) {
        Thread1 t1=new Thread1();
        Thread2 t2=new Thread2();
        t1.start();
        t2.start();
        System.out.println(Thread.currentThread().getName()+" holds the lock"+Thread.holdsLock(i));
    }

    static class Thread1 extends Thread{

        public void run(){
            while(true){
                synchronized(i){
                    System.out.println(this.getName()+" holds the lock"+Thread.holdsLock(i));
                    if(i>0)
                    i--;
                    System.out.println(this.getName()+":"+i);
                    i.notify();
                    try {
                        i.wait();
                        System.out.println("线程1 等待");
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                //i.notify();
            }
        }
    }

    static class Thread2 extends Thread{

        public void run(){
            while(true){
                synchronized(i){
                    System.out.println(this.getName()+" holds the lock"+Thread.holdsLock(i));
                    if(i<100)
                    i++;
                    System.out.println(this.getName()+":"+i);
                    i.notify();
                    try {
                        i.wait();
                        System.out.println("线程2等待");
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                //i.notify();
            }
        }
    }

}

代码改为如下: 正常运行。

package blockthread;

public class DeadLock {

    public static void main(String[] args) {
        Instance instance=new Instance();
        Thread1 t1=new Thread1(instance);
        Thread2 t2=new Thread2(instance);
        t1.start();
        t2.start();
        System.out.println(Thread.currentThread().getName()+" holds the lock"+Thread.holdsLock(instance));
    }

    static class Thread1 extends Thread{
        private Instance instance;

        public Thread1(Instance instance){
            this.instance=instance;
        }

        public void run(){
            while(true){
                synchronized(instance){
                    System.out.println(this.getName()+" holds the lock"+Thread.holdsLock(instance));
                    if(instance.getI()>0){
                        int i=instance.getI();
                        i--;
                    }
                    System.out.println(this.getName()+":"+instance.getI());
                    instance.notify();
                    try {
                        instance.wait();
                        System.out.println("线程1 等待");
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                //i.notify();
            }
        }
    }

    static class Thread2 extends Thread{
private Instance instance;

        public Thread2(Instance instance){
            this.instance=instance;
        }
        public void run(){
            while(true){
                synchronized(instance){
                    System.out.println(this.getName()+" holds the lock"+Thread.holdsLock(instance));
                    if(instance.getI()<100){
                        int i=instance.getI();
                        i++;
                    }
                    System.out.println(this.getName()+":"+instance.getI());
                    instance.notify();
                    try {
                        instance.wait();
                        System.out.println("线程2等待");
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                //i.notify();
            }
        }
    }

}
class Instance{
    private int i=100;

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }
}
时间: 2024-10-29 16:25:19

加锁问题,必须加锁在对象上或方法上,加在基本数据类型上无效的相关文章

加锁的位置 (eq:map&lt;key,map&lt;&gt;&gt; 双集合 怎么 只加锁 在用到的对象位置,而不是把整个集合锁住)

比如上边的map里套map 定义变量为data,例如组队副本 npc 为1 下有众多房间 即Map<1,<roomId,room>> ,处于多线程下,一个线程在 npc为1的下边建一个房间,房间id为1即Map<1,<1,room>> ,这时候另外一个线程同时也要在 npc为1下建一个房间id为2的房间 即 Map<1,<2,room>> ,那我代码里肯定是 先 <roomId,room> rooms  =  data.g

POSIX 线程详解(3-互斥量:&quot;固定加锁层次&quot;/“试加锁-回退”)

有时一个互斥量是不够的: 比如: 当多个线程同时访问一个队列结构时,你需要2个互斥量,一个用来保护队列头,一个用来保护队列元素内的数据. 当为多线程建立一个树结构时,你可能需要为每个节点设置一个互斥量. 同时使用多个互斥量会导致复杂度的增加 最坏的情况就是死锁的发生,即两个线程分别锁住一个互斥量而等待对方的互斥量. 多互斥量可能导致死锁: 如果可以在独立的数据上使用两个分离的互斥量,那么就应该这么做.这样,通过减少线程必须等待其他线程完成数据操作的时间. 如果数据独立,则某个特定函数就不太可能经

POSIX 线程具体解释(3-相互排斥量:&quot;固定加锁层次&quot;/“试加锁-回退”)

有时一个相互排斥量是不够的: 比方: 当多个线程同一时候訪问一个队列结构时,你须要2个相互排斥量,一个用来保护队列头,一个用来保护队列元素内的数据. 当为多线程建立一个树结构时.你可能须要为每一个节点设置一个相互排斥量. 同一时候使用多个相互排斥量会导致复杂度的添加 最坏的情况就是死锁的发生.即两个线程分别锁住一个相互排斥量而等待对方的相互排斥量. 多相互排斥量可能导致死锁: 假设能够在独立的数据上使用两个分离的相互排斥量,那么就应该这么做. 这样,通过降低线程必须等待其它线程完毕数据操作的时间

Android加载手机磁盘上的资源---decodeFile方法的使用

一般在写Android程序时,通常会将图片资源放在/res/drawable/文件夹下,读取时,通过R.drawable.imageId即可读取图片内容,但用户在使用时,一般会想要读取存放在存储卡上的资源,这时候上面的方法将不起作用,这时候,就需要使用Bitmap和BitmapFactory对象,来加载手机磁盘上的资源了. 首先在布局文件里放一个ImageView,用户放置图片,图片存放的路径为/data/data/demo.jpg,在程序中首先获取ImageView,代码如下: ImageVi

ajax结合文件上传类进行多文件的单个上传

今天做项目的时候碰见一个问题:之前一个同事离职之前做了一个网站,有一个上传商品详细图片的功能,当时已经完成,但是由于后期程序的有更改以及更改的程序员的水平也是参差不齐,最后导致程序bug很多,由于当时用的是一个框架,最终也没找到说明文档,后来我就重新写了一个结合ajax上传文件的upload.classs.php虽然界面欠缺美观,但是通俗易懂好维护. //首先是页面. index.php <!DOCTYPE html> <html lang="en"> <

六星经典CSAPP-笔记(7)加载与链接(上)

六星经典CSAPP-笔记(7)加载与链接 1.对象文件(Object File) 1.1 文件类型 对象文件有三种形式: 可重定位对象文件(Relocatable object file):包含二进制代码和数据,能与其他可重定位对象文件在编译时合并创建出一个可执行文件. 可执行对象文件(Executable object file):包含可以直接拷贝进行内存执行的二进制代码和数据. 共享对象文件(Shared object file):一种特殊的可重定位对象文件,能在加载时或运行时,装载进内存进

vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件

vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件/库 一提到移动端的下拉刷新上拉翻页,你可能就会想到iScroll插件,没错iScroll是一个高性能,资源占用少,无依赖,多平台的javascript滚动插件.iScroll不仅仅是 滚动.它可以处理任何需要与用户进行移动交互的元素.在你的项目中包含仅仅4kb大小的iScroll,你的项目便拥有了滚动,缩放,平移,无限滚动,视差滚动,旋转功能.iScroll的强大毋庸置疑,本人也非常欢迎大家使用iScr

Plupload 上传详细讲解,Plupload 多实例上传,Plupload多个上传按钮--推荐使用

今天帮朋友解决  Plupload  上传的问题,查了很多资料,资料还是挺全的,但是有点零零散散的,故整理好,合并发出来. 本教程包括: Plupload  上传详细讲. Plupload  多实例上传. Plupload  多个上传按钮. Plupload  上传成功获取返回值. 我们来看一个比较全的  Plupload  Demo <!DOCTYPE html> <html> <head> <meta charset="UTF-8">

Android中自定义MultipartEntity实现文件上传以及使用Volley库实现文件上传

最近在参加CSDN博客之星,希望大家给投一票,谢谢啦~                       点这里投我一票吧~ 前言 在开发当中,我们常常需要实现文件上传,比较常见的就是图片上传,比如修改个头像什么的.但是这个功能在Android和iOS中都没有默认的实现类,对于Android我们可以使用Apache提供的HttpClient.jar来实现这个功能,其中依赖的类就是Apache的httpmime.jar中的MultipartEntity这个类.我就是要实现一个文件上传功能,但是我还得下载