面试题:写一个程序证明StringBuffer是线程安全的,而StringBuilder是线程不安全的

tiancaixuchao2009 2013-08-22 08:40:27
同学去趋势科技实习生的面试题,回来大骂面试官怎么出个这么个题。我平时也是看书知道StringBuffer是线程安全的,另一个是不安全的,但是从来没实证过。哪位大神能写个程序演示一下线程安全和不安全的情况?
...全文
510 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
失落夏天 2013-08-23
  • 打赏
  • 举报
回复
这个题我感觉很基础,线程安全和不安全的区别是什么? 我们判断的话就去分别创建这两个对象,来多线程对这两个对象进行存于读的操作就好了。 实习生说实在的面试也只能靠些这些基本的,要不还能问所谓的校园项目么?
zyrobert 2013-08-23
  • 打赏
  • 举报
回复
引用 3 楼 fortheother 的回复:
package cn.dzr.thread;

import org.omg.PortableInterceptor.CurrentHelper;

class DelStr implements Runnable
{

	StringBuilder sb;
	DelStr(StringBuilder sb)
	{
		this.sb = sb;
	}
	public void run()
	{
		for(int i =0;i<sb.length();)
		{
			
			
			try
			{
				Thread.sleep(10);
			}
			catch (InterruptedException e)
			{
				e.printStackTrace();
			}
			sb.deleteCharAt(i);
			
		}
	}
}
public class StringBuilderTest
{
	public static void main(String[] args)
	{
		StringBuilder sb = new StringBuilder("abcdefgh");
		new Thread(new DelStr(sb)).start();
		new Thread(new DelStr(sb)).start();
		
		
	}
}
楼上这个代码用stringbuffer在删除最后一个点是会出现越界报错
kemucc 2013-08-23
  • 打赏
  • 举报
回复
public class Test {
    public static void main(String[] args) {
        StringBuffer sbf = new StringBuffer();
        StringBuilder sb = new StringBuilder();
        //10个线程
        for (int i = 0; i < 10; i++) {
            new Thread(new TestThread(sbf, sb)).start();
        }
    }
}

class TestThread implements Runnable {
    StringBuffer sbf;
    StringBuilder sb;

    TestThread(StringBuffer sbf, StringBuilder sb) {
        this.sb = sb;
        this.sbf = sbf;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            sb.append("1");
            sbf.append("1");
            System.out.println(sb.length() + "/" + sbf.length());
        }
    }
}
kemucc 2013-08-23
  • 打赏
  • 举报
回复
这个,分别新建两种对象的实例,用几个线程循环写入干预它们,最后再读取就可以了吧……
zyrobert 2013-08-23
  • 打赏
  • 举报
回复
楼上的代码看不懂 有大神给解释一下么?
失落夏天 2013-08-23
  • 打赏
  • 举报
回复
引用 4 楼 zyrobert 的回复:
[quote=引用 3 楼 fortheother 的回复:]
package cn.dzr.thread;

import org.omg.PortableInterceptor.CurrentHelper;

class DelStr implements Runnable
{

	StringBuilder sb;
	DelStr(StringBuilder sb)
	{
		this.sb = sb;
	}
	public void run()
	{
		for(int i =0;i<sb.length();)
		{
			
			
			try
			{
				Thread.sleep(10);
			}
			catch (InterruptedException e)
			{
				e.printStackTrace();
			}
			sb.deleteCharAt(i);
			
		}
	}
}
public class StringBuilderTest
{
	public static void main(String[] args)
	{
		StringBuilder sb = new StringBuilder("abcdefgh");
		new Thread(new DelStr(sb)).start();
		new Thread(new DelStr(sb)).start();
		
		
	}
}
楼上这个代码用stringbuffer在删除最后一个点是会出现越界报错[/quote] 越界的原因是什么呢? 多线程的缘故,不过我感觉这个例子似乎并不能说明线程安全和不安全, 附一个我的例子吧,

public class Test3 implements Runnable {
//    StringBuilder builder = new StringBuilder();
    StringBuffer buffer=new StringBuffer();
    public void run() {
        try {
            Thread.sleep((int)(Math.random() * 2));
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
//      builder.append(1);
        buffer.append(1);
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadGroup group = new ThreadGroup("testgroup");
        Test3 t = new Test3();
        for (int i = 0; i < 100000; i++) {
            Thread th = new Thread(group, t, String.valueOf(i));
            th.start();
        }
       
        while (group.activeCount() > 0) {
            Thread.sleep(10);
        }
     // 如果长度为100000就是安全的
//      System.out.println(t.builder.length()); 
        System.out.println(t.buffer.length());
    }
}
2013-08-22
  • 打赏
  • 举报
回复
package cn.dzr.thread;

import org.omg.PortableInterceptor.CurrentHelper;

class DelStr implements Runnable
{

	StringBuilder sb;
	DelStr(StringBuilder sb)
	{
		this.sb = sb;
	}
	public void run()
	{
		for(int i =0;i<sb.length();)
		{
			
			
			try
			{
				Thread.sleep(10);
			}
			catch (InterruptedException e)
			{
				e.printStackTrace();
			}
			sb.deleteCharAt(i);
			
		}
	}
}
public class StringBuilderTest
{
	public static void main(String[] args)
	{
		StringBuilder sb = new StringBuilder("abcdefgh");
		new Thread(new DelStr(sb)).start();
		new Thread(new DelStr(sb)).start();
		
		
	}
}
2013-08-22
  • 打赏
  • 举报
回复
让两个线程同时向这个字符串里进行增删改就好了。 一般涉及到对数据的修改,都会出现问题。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧