不同线程之间如何传参?

发布时间:2024年01月21日

假设在主线程中的某个对象需要传入到另外一个线程中进行处理,那么两个线程之间如何传递参数?例如:主程序中有个字符串String s = "hello world";,使用异步子线程进行空格拆分,结果应该输出helloworld两个单词,实现方式如下:

第一种方式

这种方式其实不是参数传递,而是子线程和主线程共享同一个字符串对象,使用log.debug日志可以看到线程信息,你可以替换为System.out.println();

@Slf4j
public class ThreadTest1  {
    public static void main(String[] args) throws InterruptedException {
        String s = "hello world";
        log.debug(s);
        new Thread(()->{
            String[] res = s.split(" ");
            log.debug(res[0]);
            log.debug(res[1]);
        }).start();
        Thread.sleep(1000);
    }
}

第二种方式

如果采用实现Runnable的方式应该如何实现呢?如下:

public class ThreadTest3 implements Runnable { 
	public static void main(String[] args) throws InterruptedException {
        new ThreadTest3().handler();
    }
    public void handler() throws InterruptedException {
        String s = "hello world";
        log.debug(s);
		// 这里应该写入你的代码
		
        Thread.sleep(1000);
    }

    @Override
    public void run() {
    	// 这里应该进行字符串分割
    }
}

这里还是使用共享参数的方式,将字符串抽取为成员方法,然后在handler()中将局部变量赋值给成员变量即可。这里使用牛一点的实现,使用任务队列的方式实现。好处是如果有非常多的变量,创建太多的成员变量非常不友好,不如直接将需要执行的指令加入到任务队列中,需要执行时取出即可。注意:任务队列的任务也必须在当前类的作用域中,否则空指针。如下:

@Slf4j
public class ThreadTest3 implements Runnable {
    // 任务队列,存放可执行的命令,两个线程需要传参的话通过队列来实现执行逻辑解耦
    private static final ConcurrentLinkedQueue<Runnable> tasks = new ConcurrentLinkedQueue<>();
    public static void main(String[] args) throws InterruptedException {
        new ThreadTest3().handler();
    }
    public void handler() throws InterruptedException {
        String s = "hello world";
        log.debug(s);
        tasks.add(()->{
            String[] res = s.split(" ");
            log.debug(res[0]);
            log.debug(res[1]);
        });
        new Thread(this).start();
        Thread.sleep(1000);
    }

    @Override
    public void run() {
        Runnable task = tasks.poll();
        if(task!=null){
            task.run();
        }
    }
}

第三种实现

其实前面两种都是共享参数,并没有真的传递参数,这里创建新的Runnable实现类来达到真正的参数传递:

public class ThreadTest2 { 
    public static void main(String[] args) throws InterruptedException {
        String s = "hello world";
        log.debug(s);
        new Thread(new Handler(s)).start();
        Thread.sleep(1000);
    }

    static class Handler implements Runnable{
        String s;
        Handler(String s){
            this.s = s;
        }
        @Override
        public void run() {
            String[] res = s.split(" ");
            log.debug(res[0]);
            log.debug(res[1]);
        }
    }
}

结果输出

输出结果除了类名不同,应该都是输出如下内容:

20:02:02 [DEBUG] [main] c.c.ThreadTest2 - hello world
20:02:02 [DEBUG] [Thread-0] c.c.ThreadTest2 - hello
20:02:02 [DEBUG] [Thread-0] c.c.ThreadTest2 - world

文章来源:https://blog.csdn.net/cj151525/article/details/135733970
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。