Solo  当前访客:3 登录 注册

喧哗博客-http://blog.xuahua.com

繁华过后的沉寂--技术经验分享
浏览次数: 95,037    文章总数: 91    评论总数: 3
标签:

visual VM 监听远程内存 提示无法使用 service:jmx:rmi:///jndi/rmi:///jmxrmi

1,启动参数

  

java -Djava.rmi.server.hostname=xxx -Djava.security.policy=jstatd.all.policy -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=8888
-Xmx256m -Xms=256m -jar xxx.jar

 

2,需要开启监听的二个随机端口,如果这两个端口访问不了,会提示 

VisualVM 无法使用 service:jmx:rmi:///jndi/rmi:///jmxrmi 连接到XX.xx.xx.xx 

 

如何查看,如下命令

netstat -tupln |grep {要监听java进程id}

3,命令查看内存占用情况分布

jstat -gcutil xxx 200 3

 

 

java并发编程之栅栏(CyclicBarrier)与闭锁(Latch) 有更新!

如果想实现所有的线程一起等待某个事件的发生,当某个事件发生时,所有线程一起开始往下执行的话,有什么好的办法吗?

方法1,栅栏CyclicBarrier

方法2 ,闭锁 Latch


栅栏与闭锁(Latch)的差异在于:


    闭锁   Latch 


一种同步方法,可以延迟线程的进度直到线程到达某个终点状态。通俗的讲就是,一个闭锁相当于一扇大门,在大门打开之前所有线程都被阻断,一旦大门打开所有线程都将通过,

但是一旦大门打开,所有线程都通过了,那么这个闭锁的状态就失效了,门的状态也就不能变了,只能是打开状态。

也就是说闭锁的状态是一次性的,它确保在闭锁打开之前所有特定的活动都需要在闭锁打开之后才能完成。


   应用场景:


  • 确保某个计算在其需要的所有资源都被初始化之后才继续执行。二元闭锁(包括两个状态)可以用来表示“资源R已经被初始化”,而所有需要R的操作都必须先在这个闭锁上等待。
  • 确保某个服务在其依赖的所有其他服务都已经启动之后才启动。
  • 等待直到某个操作的所有参与者都就绪在继续执行。(例如:多人游戏中需要所有玩家准备才能开始)


            CountDownLatch是JDK 5+里面闭锁的一个实现,允许一个或者多个线程等待某个事件的发生。CountDownLatch有一个正数计数器,countDown方法对计数器做减操作,await方法等待计数器达到0。

         所有await的线程都会阻塞直到计数器为0或者等待线程中断或者超时。


         代码例子: 

                   

    栅栏  CyclicBarrier


 栅栏类似于闭锁,它能阻塞一组线程直到某个事件发生。栅栏与闭锁的关键区别在于,所有的线程必须同时到达栅栏位置,才能继续执行。闭锁用于等待事件,而栅栏用于等待其他线程。


     场景:

 应用一些协议,比如几个家庭成员决定在某个地方集合,所有人在6:00在某地集合,到了以后要等待其他人,之后才能讨论去哪里吃饭。

 并行迭代,将一个问题分成很多子问题,当一系列的子问题都解决之后(所有子问题线程都已经await()),此时将栅栏打开,所有子问题线程被释放,而栅栏位置可以留着下次使用。



  例子:两个分别关于CountDownlatch和CyclicBarrier的例子

1、CountDownLatch


    有三个工人在为老板干活,这个老板有一个习惯,就是当三个工人把一天的活都干完了的时候,他就来检查所有工人所干的活。记住这个条件:三个工人先全部干完活,老板才检查。所以在这里用Java代码设计两个类,Worker代表工人,Boss代表老板,具体的代码实现如下:


    工人:


              

package LatchAndCyclicBarrier;

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class Work implements Runnable{


        private CountDownLatch downLatch;
        private String name;

        public Work(CountDownLatch downLatch, String name){
            this.downLatch = downLatch;
            this.name = name;
        }

        public void run() {
            this.doWork();
            try{
                TimeUnit.SECONDS.sleep(new Random().nextInt(10));
            }catch(InterruptedException ie){
            }
            System.out.println(this.name + "活干完了!");
            this.downLatch.countDown();

        }

        private void doWork(){
            System.out.println(this.name + "正在干活!");
        }

    }


老板:

 

package LatchAndCyclicBarrier;

import java.util.concurrent.CountDownLatch;

public class Boss implements Runnable{

        private CountDownLatch downLatch;

        public Boss(CountDownLatch downLatch){
            this.downLatch = downLatch;
        }

        public void run() {
            System.out.println("老板正在等所有的工人干完活......");
            try {
                this.downLatch.await();
            } catch (InterruptedException e) {
            }
            System.out.println("工人活都干完了,老板开始检查了!");
        }

    }

测试代码: 




package LatchAndCyclicBarrier;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestLatch {

    public static void main(String[] args) {
            ExecutorService executor = Executors.newCachedThreadPool();

            CountDownLatch latch = new CountDownLatch(3);

            Work w1 = new Work(latch,"张三");
            Work w2 = new Work(latch,"李四");
            Work w3 = new Work(latch,"王二");

            Boss boss = new Boss(latch);

            executor.execute(w3);
            executor.execute(w2);
            executor.execute(w1);
            executor.execute(boss);

            executor.shutdown();
        }

    }
执行结果:
李四正在干活!
老板正在等所有的工人干完活......
王二正在干活!
张三正在干活!
李四活干完了!
王二活干完了!
张三活干完了!
工人活都干完了,老板开始检查了!

2、CyclicBarrier


接着上面的例子,还是这三个工人,不过这一次,这三个工人自由了,老板不用检查他们任务了,他们三个合作建桥,有三个桩,每人打一个,同时打完之后才能一起搭桥(搭桥需要三人一起合作)。也就是说三个人都打完桩之后才能继续工作。

   








package LatchAndCyclicBarrier;

import java.util.concurrent.CyclicBarrier;

public class CycWork implements Runnable {


        private CyclicBarrier cyclicBarrier ;
        private String name ;

        public CycWork(CyclicBarrier cyclicBarrier,String name)
       {
               this .name =name;
               this .cyclicBarrier =cyclicBarrier;
       }

        @Override
        public void run() {
               // TODO Auto-generated method stub

              System. out .println(name +"正在打桩,毕竟不轻松。。。。。" );

               try {
                     Thread. sleep(5000);
                     System. out .println(name +"不容易,终于把桩打完了。。。。" );
                      cyclicBarrier .await();

              } catch (Exception e) {
                      // TODO: handle exception
                     e.printStackTrace();
              }

              System. out .println(name +":其他逗b把桩都打完了,又得忙活了。。。" );


       }

}
测试程序:
 
package LatchAndCyclicBarrier;

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CycTest {

        public static void main(String[] args)
       {
              ExecutorService executorpool=Executors. newFixedThreadPool(3);
              CyclicBarrier cyclicBarrier= new CyclicBarrier(3);

              CycWork work1= new CycWork(cyclicBarrier, "张三" );
              CycWork work2= new CycWork(cyclicBarrier, "李四" );
              CycWork work3= new CycWork(cyclicBarrier, "王五" );

              executorpool.execute(work1);
              executorpool.execute(work2);
              executorpool.execute(work3);

              executorpool.shutdown();

       }

}
运行结果:
 
李四正在打桩,毕竟不轻松。。。。。
张三正在打桩,毕竟不轻松。。。。。
王五正在打桩,毕竟不轻松。。。。。
李四不容易,终于把桩打完了。。。。
张三不容易,终于把桩打完了。。。。
王五不容易,终于把桩打完了。。。。
王五:其他逗b把桩都打完了,又得忙活了。。。
李四:其他逗b把桩都打完了,又得忙活了。。。
张三:其他逗b把桩都打完了,又得忙活了。。。 
 

CountDownlatch和CyclicBarrierde 源码部分

1、CountDownLatch中的两个关键方法

 public void countDown() {    //对计数器减一 表示有一个事件已经发生了
        sync.releaseShared(1); 
    }
public void await() throws InterruptedException { //等到计数器为0
        sync.acquireSharedInterruptibly(1);
    }
await方法调用了AbstractQueuedSynchronizer中的acquireSharedInterruptibly
 
public final void acquireSharedInterruptibly (int arg)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        if (tryAcquireShared(arg) < 0)
            doAcquireSharedInterruptibly(arg);
    }
public final boolean releaseShared (int arg) {
        if (tryReleaseShared(arg)) {   
            doReleaseShared();
            return true ;
        }
        return false ;
    }
protected boolean tryReleaseShared (int arg) {
        throw new UnsupportedOperationException();
    }
2、CyclicBarrier中的await()方法
 
public int await() throws InterruptedException, BrokenBarrierException {
        try {
            return dowait(false, 0L);
        } catch (TimeoutException toe) {
            throw new Error(toe); // cannot happen;
        }
    }
 private int dowait(boolean timed, long nanos)
        throws InterruptedException, BrokenBarrierException,
               TimeoutException {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            final Generation g = generation;

            if (g.broken)
                throw new BrokenBarrierException();

            if (Thread.interrupted()) {
                breakBarrier();
                throw new InterruptedException();
            }

           int index = --count;
           if (index == 0) {  // tripped
               boolean ranAction = false;
               try {
                   final Runnable command = barrierCommand;
                   if (command != null)
                       command.run();
                   ranAction = true;
                   nextGeneration();
                   return 0;
               } finally {
                   if (!ranAction)
                       breakBarrier();
               }
           }

            // loop until tripped, broken, interrupted, or timed out
            for (;;) {
                try {
                    if (!timed)
                        trip.await();
                    else if (nanos > 0L)
                        nanos = trip.awaitNanos(nanos);
                } catch (InterruptedException ie) {
                    if (g == generation && ! g.broken) {
                        breakBarrier();
                        throw ie;
                    } else {
                        // We‘re about to finish waiting even if we had not
                        // been interrupted, so this interrupt is deemed to
                        // "belong" to subsequent execution.
                        Thread.currentThread().interrupt();
                    }
                }

                if (g.broken)
                    throw new BrokenBarrierException();

                if (g != generation)
                    return index;

                if (timed && nanos <= 0L) {
                    breakBarrier();
                    throw new TimeoutException();
                }
            }
        } finally {
            lock.unlock();
        }
    }
上面dowait方法中有一个index,index=--count而count的值在源码中来自

count = parties;
提到 parties就不得不看看构造函数了 

public CyclicBarrier(int parties) {
        this(parties, null);
    }
如上例子,我们构造了CyclicBarrier(3)那么此时的 count值为3,接着dowait源码,当index==0时,后面执行的

final Runnable command = barrierCommand;
其实是可以设置的,这个Runnable可以传进来,当我们希望所有线程都达到某一时刻之后,用什么线程执行接下来的工作,
当没有传Runnable进来时,就继续执行(唤醒其他线程),否则就runnable.run()(唤醒其他线程之前执行) 
原文:http://blog.csdn.net/yujin753/article/details/46125283


java进阶之一生成二维码

生成二维码图片,指定内容,生成图片提供下载。


/**
	 * 生成二维码并返回图片路径
	 * @param domain
	 * @param SERVER_PATH
	 * @param filepath
	 * @param content
	 * @param imgPath
	 * @param filename
	 * @param needCompress
	 * @return
	 * @throws Exception
	 * 
	 * String path_ = QRCodeUtil.buildcodeurl(Constants.getConfigkey("upload.image.base64.domain"),
					Constants.getConfigkey("common.file.path"),"/qrcode/user/",
					Constants.getConfigkey("h5.cus.url")+"/reg?cid="+o.getId()
					, null,o.getId()+".jpg");
	 */
	public static String buildcodeurl(String domain,String SERVER_PATH,String filepath,String content, String imgPath,String filename) throws Exception{
		String path = SERVER_PATH+filepath;
		QRCodeUtil.encode(content, imgPath, path,filename, true);
		String path_ = domain+filepath+filename;
		return path_;
		
	}

/**
	 * 生成二维码(内嵌LOGO)
	 * 
	 * @param content
	 *            内容
	 * @param imgPath
	 *            LOGO地址
	 * @param destPath
	 *            存放目录
	 * @param needCompress
	 *            是否压缩LOGO
	 * @throws Exception
	 */
	public static void encode(String content, String imgPath, String destPath,String filename,
			boolean needCompress) throws Exception {
		BufferedImage image = QRCodeUtil.createImage(content, imgPath,
				needCompress);
		mkdirs(destPath);
		String file = filename;
		File f = new File(destPath+"/"+file);
		if(!f.getParentFile().exists()){
			f.getParentFile().mkdirs();
		}
		ImageIO.write(image, FORMAT_NAME,f);
	}

整个源文件下载  http://file.xuahua.com/blog/2016/0806/QRCodeUtil.java


公告

喧哗博客--繁华过后的沉寂--技术经验分享^-^
Copyright (c) 2009-2019, b3log.org & hacpai.com