<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def scan(self, proxy_scanner, expected_num=20, val_thr_num=4, queue_timeout=3, val_timeout=5, out_file='proxies.json'):
 """Scan and validate proxies Firstly, call the `scan` method of `proxy_scanner`, then using multiple threads to validate them. Args: proxy_scanner: A ProxyScanner object. expected_num: Max number of valid proxies to be scanned. val_thr_num: Number of threads used for validating proxies. queue_timeout: Timeout for getting a proxy from the queue. val_timeout: An integer passed to `is_valid` as argument `timeout`. out_file: A string or None. If not None, the proxies will be saved into `out_file`. """

        try:
            proxy_scanner.scan()
            self.logger.info('starting {} threads to validating proxies...'
                             .format(val_thr_num))
            val_threads = []
            for i in range(val_thr_num):
                t = threading.Thread(
                    name='val-{:0>2d}'.format(i + 1),
                    target=self.validate,
                    kwargs=dict(
                        proxy_scanner=proxy_scanner,
                        expected_num=expected_num,
                        queue_timeout=queue_timeout,
                        val_timeout=val_timeout))
                t.daemon = True
                val_threads.append(t)
                t.start()
            for t in val_threads:
                t.join()
            self.logger.info('Proxy scanning done!')
        except:
            raise
        finally:
            if out_file is not None:
                self.save(out_file)